歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

ARM 如何實現絕對地址的跳轉

基於 b跳轉指令,ldr偽指令,ldr加載指令分析

有以下場景需用到

1.實現從Stepingstone中執行部分指令後,需跳轉到SDRAM中執行,前提是必須先將NAND FLASH中代碼copy到SDRAM,然後才能跳轉到SDRAM去執行。跳轉到SDRAM 需使用LDR偽指令LDR PC,=SDRAM 來實現

分析:

b指令是相對跳轉指令,可以看到起反匯編代碼是完全一樣的,它依賴於當前PC寄存器的值,不管此代碼鏈接地址如何,b指令都可以跳轉到正確位置,這類指令稱為位置無關指令

ldr pc,=labr 偽指令,從反匯編代碼可以看出,是從內存的某個位置讀出數據,並賦給pc寄存器,其中存放的值依賴於鏈接腳本文件的鏈接地址。是絕對跳轉指令。

2.在SDRAM中實現中斷的調試,必須將中斷向量也在0x00000000位置放置,讓其跳轉到SDRAM對應位置

  1. Vectors           
  2.         ldr     PC, Reset_Addr     ;@0x00復位      
  3.         ldr     PC, Undef_Addr  ;@ 0x04: 未定義指令中止模式的向量地址  
  4.         ldr     PC, SWI_Addr        ;@ 0x08: 管理模式的向量地址,通過SWI指令進入此模式  
  5.         ldr     PC, PAbt_Addr       ;@ 0x0c: 指令預取終止導致的異常的向量地址  
  6.         ldr     PC, DAbt_Addr       ;@ 0x10: 數據訪問終止導致的異常的向量地址  
  7.         nop                     ;@ 0x14: 保留  
  8.         ldr     PC, IRQ_Addr        ;@ 0x18: 中斷模式的向量地址  
  9.         ldr        PC, FIQ_Addr     ;@ 0x1c: 快中斷模式的向量地址  
  10. Reset_Addr          DCD     Reset_Handler  
  11. Undef_Addr      DCD     Undef_Handler  
  12. SWI_Addr        DCD     SWI_Handler  
  13. PAbt_Addr       DCD     PAbt_Handler  
  14. DAbt_Addr       DCD     DAbt_Handler  
  15.                     nop  
  16. IRQ_Addr        DCD     IRQ_Handler  
  17. FIQ_Addr        DCD     FIQ_Handler  
  18. Reset_Handler                  
  19.     <…對應指令代碼 …>  
  20. Undef_Handler   b   Undef_Handler   ;未用到,可以用此指令保留  
  21. SWI_Handler     b   SWI_Handler     ;未用到,可以用此指令保留  
  22. PAbt_Handler        b   PAbt_Handler        ;未用到,可以用此指令保留  
  23. DAbt_Handler        b   DAbt_Handler        ;未用到,可以用此指令保留  
  24. FIQ_Handler     b   FIQ_Handler     ;未用到,可以用此指令保留  
  25. IRQ_Handler  
  26.         sub lr, lr, #4                  ;@ 計算返回地址  
  27.         stmdb   sp!,    { r0-r12,lr }   ;@ 保存使用到的寄存器  
  28.                                     ;@ 注意,此時的sp是中斷模式的sp  
  29.                                      ;@ 初始值是上面設置的3072  
  30.         ldr lr , =int_return  
  31.         ldr pc, =EINT_Handle            ;@ 調用中斷服務函數,在interrupt.c中  
  32. int_return          ;因為ldr跳轉不能夠把下一條指令的地址保存到lr,所以需要在跳轉之前字寫指令保存起來,  
  33.     ldmia   sp!,    { r0-r12,pc }^   ;@ 中斷返回, ^表示將spsr的值復制到cpsr  
  34.     END  
Copyright © Linux教程網 All Rights Reserved