adr和ldr的区别
同學們在學習ARM指令時,多數都會對adr和ldr這兩個命令產生疑惑,那他們究竟有什么區別呢?
其實這兩個都是偽指令:adr是小范圍的地址讀取偽指令,ldr是大范圍的讀取地址偽指令。可實際上adr是將基于PC相對偏移的地址值或基于寄存器相對地址值讀取的為指令,而ldr用于加載32為立即數或一個地址到指定的寄存器中。到這兒就會看到其中的區別了。如果在程序中想加載某個函數或者某個在聯接時候指定的地址時請使用adr,例如在lds中需要重新定位的地址。當加載32為的立即數或外部地址時請用ldr。
我給大家先舉個例子:
? ? ? ? AREA test,CODE,READONLY
????????ENTRY
? ? ? ? ldr r0,_start
????????adr r0,_start
????????ldr r0,=_start
????????nop
????????
_start
????????nop
????????END
這段代碼并無實際意義,只是為了方便說明。我們反匯編一下看看:
? ? ? ? 4: ? ? ? ? ? ? ? ? ?ldr????? r0,_start
????????0x00000000????????? E59F0008????? LDR ??????R0,[PC,#0x0008]
????????5: ???????????????? adr ?????r0,_start?
????????0x00000004????????? E28F0004 ??????ADD????? R0,PC,#0x00000004
????????6: ???????????????? ldr????? r0,=_start?
????????0x00000008????????? E59F0004????? LDR?????? R0,[PC,#0x0004]
????????7: ???????????????? nop?
????????8:?
????????9:?
????????10: _start?
????????0x0000000C?????????? E1A00000 ??????????NOP?
????????11: ??????????nop
ldr ??????????r0, _start
從內存地址 _start 的地方把值讀入。執行這個后,r0 = 0xe1a00000
adr???????? r0, _start
取得 _start 的地址到 r0,但是請看反編譯的結果,它是與位置無關的。其實取得的時相對的位置。例如這段代碼在 0x00000000 運行,那么 adr r0, _start 得到 r0 = 0x00000010;
ldr ???????? r0, =_start
這個取得標號 _start 的絕對地址。這個絕對地址是在 link 的時候確定的。看上去這只是一個指令,但是它要占用 2 個 32bit 的空間,一條是指令,另一條是 _start 的數據(因為在編譯的時候不能確定 _start 的值,而且也不能用 mov 指令來給 r0 賦一個 32bit 的常量,所以需要多出一個空間存放 _start 的真正數據,在這里就是 0x0000000c)。
因此可以看出,這個是絕對的尋址,不管這段代碼在什么地方運行,它的結果都是 r0 = 0x0000000c。
? ? ? ?
總結
以上是生活随笔為你收集整理的adr和ldr的区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ADS错误(Fatal)L6002U解决
- 下一篇: ARM9五级流水线