基於 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對應位置
- Vectors
- ldr PC, Reset_Addr ;@0x00復位
- ldr PC, Undef_Addr ;@ 0x04: 未定義指令中止模式的向量地址
- ldr PC, SWI_Addr ;@ 0x08: 管理模式的向量地址,通過SWI指令進入此模式
- ldr PC, PAbt_Addr ;@ 0x0c: 指令預取終止導致的異常的向量地址
- ldr PC, DAbt_Addr ;@ 0x10: 數據訪問終止導致的異常的向量地址
- nop ;@ 0x14: 保留
- ldr PC, IRQ_Addr ;@ 0x18: 中斷模式的向量地址
- ldr PC, FIQ_Addr ;@ 0x1c: 快中斷模式的向量地址
- Reset_Addr DCD Reset_Handler
- Undef_Addr DCD Undef_Handler
- SWI_Addr DCD SWI_Handler
- PAbt_Addr DCD PAbt_Handler
- DAbt_Addr DCD DAbt_Handler
- nop
- IRQ_Addr DCD IRQ_Handler
- FIQ_Addr DCD FIQ_Handler
- Reset_Handler
- <…對應指令代碼 …>
- Undef_Handler b Undef_Handler ;未用到,可以用此指令保留
- SWI_Handler b SWI_Handler ;未用到,可以用此指令保留
- PAbt_Handler b PAbt_Handler ;未用到,可以用此指令保留
- DAbt_Handler b DAbt_Handler ;未用到,可以用此指令保留
- FIQ_Handler b FIQ_Handler ;未用到,可以用此指令保留
- IRQ_Handler
- sub lr, lr, #4 ;@ 計算返回地址
- stmdb sp!, { r0-r12,lr } ;@ 保存使用到的寄存器
- ;@ 注意,此時的sp是中斷模式的sp
- ;@ 初始值是上面設置的3072
- ldr lr , =int_return
- ldr pc, =EINT_Handle ;@ 調用中斷服務函數,在interrupt.c中
- int_return ;因為ldr跳轉不能夠把下一條指令的地址保存到lr,所以需要在跳轉之前字寫指令保存起來,
- ldmia sp!, { r0-r12,pc }^ ;@ 中斷返回, ^表示將spsr的值復制到cpsr
- END