這幾天看彙編,ldr和adr之間的區別總是給搞混,看了不少資料越看越暈,因而寫了個測試程序反編譯了一下一會兒都清楚了,見下面:測試
源碼:指針
adr r0, _start
nop
ldr r0, _start
nop
ldr r0, =_start
nopip
_start:
nop
mov ip, lr
源碼
反彙編以後的:編譯
8068: e28f0010 add r0, pc, #16
806c: e1a00000 nop ; (mov r0, r0)
8070: e59f0008 ldr r0, [pc, #8] ; 8080 <_start>
8074: e1a00000 nop ; (mov r0, r0)
8078: e59f0008 ldr r0, [pc, #8] ; 8088 <_start+0x8>
807c: e1a00000 nop ; (mov r0, r0)程序
00008080 <_start>:
8080: e1a00000 nop ; (mov r0, r0)
8084: e1a0c00e mov ip, lr
8088: 00008080 .word 0x00008080word
經過反彙編以後的代碼很容易就理解了:註釋
adr r0, _start;相對取址,r0中保存的是pc+16的地址:8088,這個是隨着不一樣的連接而變;ps:這個是pc指針;ps
ldr r0,_start和ldr r0,=_start;都是取值,前者取得start標號00008080處的值:e1a00000,至關於把這條指令給放進去了,執行下一條指令, (註釋:e1a00000是反彙編以後的機器讀取的指令),後者取得start標號自己的值:00008080,它存儲在8088地址地方;tar
由於adr r0, _start;r0中存在的是pc+16的pc指針地址,因此會隨着pc不一樣而變化,故稱之爲相對取址;
ldr r0,_start和ldr r0,=_start;r0中存在的都是[pc+8]的值,不會改變,故稱之爲絕對取值;