同學們在學習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
nopend
這段**並無實際意義,只是為了方便說明。我們反彙編一下看看:
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的區別
ldr指令和adr ldr偽指令的區別 ldr指令屬於load store指令,用於讀取標號位址中的值 adr ldr偽指令用於獲取標號的位址。adr和ldr偽指令的區別 adr是獲取相對pc的位址,與程式當前執行的位置相關,是小範圍的位址讀取偽指令 ldr是獲取絕對位址,絕對位址是在link的時候...
LDR與ADR的區別
ldr與adr的區別 ldr r0,start adr r0,start ldr r0,start nopmov pc,lr start nop編譯的時候設定 ro 為 0x0c008000 0c008000 start 0x14 c008000 e59f000c ldr r0,pc,12 c008...
ldr與adr的區別
參考 ldr r0,start adr r0,start ldr r0,start nopmov pc,lr start nop編譯的時候設定 ro 為 0x0c008000 0c008000 start 0x14 c008000 e59f000c ldr r0,pc,12 c008014 star...