ldr與adr的區別

2021-09-06 12:25:58 字數 2065 閱讀 7894

參考:

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

c008004:       e28f0008        add     r0, pc, #8      ; 0x8

c008008:       e59f0008        ldr     r0, [pc, #8]    ; c008018 <_start+0x4>

c00800c:       e1a00000        nop                     (mov r0,r0)

c008010:       e1a0f00e        mov     pc, lr

0c008014 <_start>:

c008014:       e1a00000        nop                     (mov r0,r0)

c008018:       0c008014        stceq   0, cr8, [r0], -#80

分析:ldr     r0, _start

從記憶體位址 _start 的地方把值讀入。執行這個後,r0 = 0xe1a00000

adr     r0, _start

取 得 _start 的位址到 r0,但是請看反編譯的結果,它是與位置無關的。其實取得的時相對的位置。例如這段**在 0x0c008000 執行,那麼 adr r0, _start 得到 r0 = 0x0c008014;如果在位址 0 執行,就是 0x00000014 了。

ldr     r0, =_start

這 個取得標號 _start 的絕對位址。這個絕對位址是在 link 的時候確定的。看上去這只是乙個指令,但是它要占用 2 個 32bit 的空間,一條是指令,另一條是 _start 的資料(因為在編譯的時候不能確定 _start 的值,而且也不能用 mov 指令來給 r0 賦乙個 32bit 的常量,所以需要多出乙個空間存放 _start 的真正資料,在這裡就是 0x0c008014)。

因此可以看出,這個是絕對的定址,不管這段**在什麼地方執行,它的結果都是 r0 = 0x0c008014

1、adr偽指令--- 小範圍的位址讀取

adr偽指令將基於pc相對偏移的位址值或基於暫存器相對偏移的位址值讀取到暫存器中。在彙編編譯器編譯源程式時,adr偽指令被編譯器替換成一條合適的指令。通常,編譯器用一條add指令或sub指令來實現該adr偽指令的功能,若不能用一條指令實現,則產生錯誤,編譯失敗。

adr偽指令格式 :adr   register, expr

當位址值是位元組對齊時,其取指範圍為: +255 ~ 255b;

當位址值是字對齊時,其取指範圍為:   -1020 ~ 1020b;

2、adrl偽指令----中等範圍的位址讀取

adrl偽指令將基於pc相對偏移的位址值或基於暫存器相對偏移的位址值讀取到暫存器中,比adr偽指令可以讀取更大範圍的位址。在彙編編譯器編譯源程式時,adrl偽指令被編譯器替換成兩條合適的指令。若不能用兩條指令實現,則產生錯誤,編譯失敗。

adrl偽指令格式:adrl   register, expr

當位址值是位元組對齊時,其取指範圍為: -64k~64k;

當位址值是字對齊時,其取指範圍為:   -256k~256k;

3、ldr偽指令-----大範圍的位址讀取

ldr偽指令用於載入32位的立即數或乙個位址值到指定暫存器。在彙編編譯源程式時,ldr偽指令被編譯器替換成一條合適的指令。若載入的常數未超出mov或mvn的範圍,則使用mov或mvn指令代替該ldr偽指令,否則彙編器將常量放入文字池,並使用一條程式相對偏移的ldr指令從文字池讀出常量。

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的區別

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

補充 adr和ldr的區別

ldr指令和adr ldr偽指令的區別 ldr指令屬於load store指令,用於讀取標號位址中的值 adr ldr偽指令用於獲取標號的位址。adr和ldr偽指令的區別 adr是獲取相對pc的位址,與程式當前執行的位置相關,是小範圍的位址讀取偽指令 ldr是獲取絕對位址,絕對位址是在link的時候...