adr和ldr的区别
同學(xué)們?cè)趯W(xué)習(xí)ARM指令時(shí),多數(shù)都會(huì)對(duì)adr和ldr這兩個(gè)命令產(chǎn)生疑惑,那他們究竟有什么區(qū)別呢?
其實(shí)這兩個(gè)都是偽指令:adr是小范圍的地址讀取偽指令,ldr是大范圍的讀取地址偽指令。可實(shí)際上adr是將基于PC相對(duì)偏移的地址值或基于寄存器相對(duì)地址值讀取的為指令,而ldr用于加載32為立即數(shù)或一個(gè)地址到指定的寄存器中。到這兒就會(huì)看到其中的區(qū)別了。如果在程序中想加載某個(gè)函數(shù)或者某個(gè)在聯(lián)接時(shí)候指定的地址時(shí)請(qǐng)使用adr,例如在lds中需要重新定位的地址。當(dāng)加載32為的立即數(shù)或外部地址時(shí)請(qǐng)用ldr。
我給大家先舉個(gè)例子:
? ? ? ? AREA test,CODE,READONLY
????????ENTRY
? ? ? ? ldr r0,_start
????????adr r0,_start
????????ldr r0,=_start
????????nop
????????
_start
????????nop
????????END
這段代碼并無實(shí)際意義,只是為了方便說明。我們反匯編一下看看:
? ? ? ? 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
從內(nèi)存地址 _start 的地方把值讀入。執(zhí)行這個(gè)后,r0 = 0xe1a00000
adr???????? r0, _start
取得 _start 的地址到 r0,但是請(qǐng)看反編譯的結(jié)果,它是與位置無關(guān)的。其實(shí)取得的時(shí)相對(duì)的位置。例如這段代碼在 0x00000000 運(yùn)行,那么 adr r0, _start 得到 r0 = 0x00000010;
ldr ???????? r0, =_start
這個(gè)取得標(biāo)號(hào) _start 的絕對(duì)地址。這個(gè)絕對(duì)地址是在 link 的時(shí)候確定的。看上去這只是一個(gè)指令,但是它要占用 2 個(gè) 32bit 的空間,一條是指令,另一條是 _start 的數(shù)據(jù)(因?yàn)樵诰幾g的時(shí)候不能確定 _start 的值,而且也不能用 mov 指令來給 r0 賦一個(gè) 32bit 的常量,所以需要多出一個(gè)空間存放 _start 的真正數(shù)據(jù),在這里就是 0x0000000c)。
因此可以看出,這個(gè)是絕對(duì)的尋址,不管這段代碼在什么地方運(yùn)行,它的結(jié)果都是 r0 = 0x0000000c。
? ? ? ?
總結(jié)
以上是生活随笔為你收集整理的adr和ldr的区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ADS错误(Fatal)L6002U解决
- 下一篇: ARM9五级流水线