補充 adr和ldr的區別

2021-08-03 14:32:53 字數 2294 閱讀 7846

ldr指令和adr、ldr指令的區別:

ldr指令屬於load-store指令,用於讀取標號位址中的值;

adr、ldr偽指令用於獲取標號的位址。

adr和ldr指令的區別:

adr是獲取相對pc的位址,與程式當前執行的位置相關,是小範圍的位址讀取偽指令;

ldr是獲取絕對位址,絕對位址是在link的時候確定的,它與程式當前執行位置無關,是大範圍讀取位址偽指令。

來看乙個例子!

彙編檔案:

ldr r0,_start

adr r0,_start

ldr r0,=_start

_start:

b _start

反彙編:

led_elf:     file format elf32-littlearm

disassembly of section .text:

00000000 <.text>:

0: e59f0004 ldr r0, [pc, #4] ; c <_start>

4: e28f0000 add r0, pc, #0 ; 0x0

8: e59f0000 ldr r0, [pc, #0] ; 10 <.text+0x10>

c: eafffffe b c <_start>

10: 0000000c andeq r0, r0, ip

1.ldr r0,_start

0:e59f0004 ldrr0, [pc, #4]; c <_start>

這是一條指令,從記憶體位址_start的位置裝載該位址存放的資料。

在這裡_start是乙個標號(是乙個相對程式的表示式),匯程式設計序計算相對於pc的偏移量,並生成相對於pc的前索引的指令:

ldr r0,[pc,#4]。指令執行後,r0=0xeafffffe(計算方法:r0 = [pc(0x00000000+8)+4]= [0x0000000c] = 0xeafffffe)。

ldr r0,_start是根據_start對當前pc的相對位置讀取其所在位址的值,因此可以在和_start標號的相對位置不變的情況下獲取資料值。

2.adr r0,_start

4:e28f0000 addr0, pc, #0; 0x0

這是一條偽指令,總是會被匯程式設計序會變為乙個指令,匯程式設計序嘗試產生單個add或sub指令來裝載該位址。

如果不能在乙個指令中構造該位址,則生成乙個錯誤,並且彙編失敗。

這裡是取得標號_start的位址到r0,因為位址是相對程式的,因此adr的產生依賴於位置的**,在此例中被彙編成:

add r0,pc,#0。因此該**可以在和標號相對位置不變的情況下移動。

假如這段**在0x30000000執行,那麼adr r0,_start得到r0 = 0x3000000c;如果在位址0執行,那麼就是0x0000000c了。(計算方法:r0 = pc(0x00000004+8)+0= 0x0000000c )。

通過這一點可以判斷程式在什麼地方執行。u-boot中那段relocate**就是通過adr實現當前程式是在ram中還是flash中。

3.ldr r0,=_start

8: e59f0000 ldrr0, [pc, #0]; 10 <.text+0x10>

這是一條偽指令,_start是乙個絕對位址(也即

執行位址

)。

這個絕對位址是在鏈結的時候確定的,它占用2個32bit的空間,一條是指令,另一條是文字池中存放_start的絕對位址。在此例中生成的指令為:

ldr r0,[pc,#0],對應文字池中的位址以及值為:0x00000010:0000000c,因此該偽指令執行後r0的值為0x0000000c。(計算方法:r0 = [pc(0x00000008+8)+0]= [0x00000010]=0x000000c)。

因此可以看出,不管這段**將來在什麼地方執行,它的結果都是r0=0x3000000c。由於ldr r0,=_start取得的是_start的絕對位址,這句**可以在_start標號的絕對位置不變的情況下移動,如使用暫存器pc在程式中可以實現絕對轉移,即實現重定位!

ldr和adr的區別

同學們在學習arm指令時,多數都會對adr和ldr這兩個命令產生疑惑,那他們究竟有什麼區別呢?其實這兩個都是偽指令 adr是小範圍的位址讀取偽指令,ldr是大範圍的讀取位址偽指令。可實際上adr是將基於pc相對偏移的位址值或基於暫存器相對位址值讀取的為指令,而ldr用於載入32為立即數或乙個位址到指...

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...