彙編指令 adr與ldr偽彙編區別

2021-10-02 20:41:49 字數 2820 閱讀 1768

adr :相對定址,與當前位置有關

ldr :絕對定址,與當前位置無關

在初始化sdram時就會用到adr,**如下:

/*   初始化sdram       */

ldr r0,

=bwscon //r0=sdram暫存器基位址,獲取絕對位址

adr r1,sdram_config //使用adr相對跳轉, r1=sdram_config位址

add r2,r0,#(13*

4)0:

ldr r3,

[r1]

,#4

str r3,

[r0]

,#4

cmp r0,r2

bne 0b

sdram_config:

.long

0x22011110

;//bwscon

.long

0x00000700

;//bankcon0

.long

0x00000700

;//bankcon1

.long

0x00000700

;//bankcon2

.long

0x00000700

;//bankcon3

.long

0x00000700

;//bankcon4

.long

0x00000700

;//bankcon5

.long

0x00018005

;//bankcon6

.long

0x00018005

;//bankcon7

.long

0x008c04f4

;//refresh

.long

0x000000b1

;//banksize

.long

0x00000030

;//mrsrb6

.long

0x00000030

;//mrsrb7

上面**中第3行之所以用到了 「 adr r1,sdram_config 」,是因為sdram未初始化之前,不能使用絕對定址,所以使用adr相對定址.

adr r1,sdram_config就相當於 ldr r1,=sdram_config

通過以下例項:

ldr r0, _start

adr r0, _start

ldr r0,

=_start

nopmov pc, lr

_start:

nop

得出以下彙編(r0設為0c008000):

0c008000 <_start-

0x14

>

:c008000: e59f000c ldr r0,

[pc, #12

]; c008014 <_start>

//ldr指令(不帶=) : r0= c008014裡面內容= e1a00000

c008004: e28f0008 add r0, pc, #8

;0x8

//adr指令: r0=(當前pc值+8)+0x8=c008014

c008008: e59f0008 ldr r0,

[pc, #8

]; c008018 <_start+

0x4>

//ldr指令(帶=) : r0=c008018 裡面內容=0c008014

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 (c008014)裡的資料放入r0中。執行這個後,r0 = 0xe1a00000

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

ldr r0,

=_start

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

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

結論:

對於adr r0,*** 就相當於 ldr r0,=*** ,通常用於sdram 未初始化之前用

arm彙編adrl(以及ldr與adr的區別)

看 嵌入式linux應用開發 第六章例項中看到個句 adrl r2,men cfg val 最初對adr1相當不解,後來發現,那個不是數字1,而是字母l 認真看頭部,有點區別的 這裡記錄下adrl的用法 功能 將相對於程式或相對於暫存器的位址載入暫存器中。與adr指令相似。adrl生成兩個資料處理指...

ARM彙編中ldr與adr的區別

ldr與adr的區別 nop編譯的時候設定 ro 為 0x0c008000 0c008000 start 0x14 c008000 e59f000c ldr r0,pc,12 c008014 start c008004 e28f0008 add r0,pc,8 0x8 c008008 e59f000...

ARM彙編中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...