在閱讀u-bootstart.s時,對adr和ldr指令有些疑惑,經韋老師指點,在參閱了一些網上的博文後,做了這個實驗:
參照韋老師的**和makefile寫了
test_adr.s:
.text
.globl _start
_start:
ldr r0,test
adr r0,test
ldr r0,=test
nop
test:
nopmakefile:
all:test_adr.s
arm-linux-gcc -c -o test_adr.o test_adr.s
arm-linux-ld -ttext 0x00000000 -g test_adr.o -o test_adr_elf
arm-linux-objcopy -o binary -s test_adr_elf test_adr.bin
arm-linux-objdump -d -m arm test_adr_elf > test_adr.dis
clean:
rm -f test_adr.dis test_adr.bin test_adr_elf *.o
對test_adr.s:反彙編得到test_adr.dis
test_adr_elf:
file format elf32-littlearm
disassembly of section .text:
00000000 <_start>:
0: e59f0008 ldr r0, [pc, #8]; 10
4: e28f0004 add r0, pc, #4; 0x4
8: e59f0004 ldr r0, [pc, #4]; 14 <.text+0x14>
c: e1a00000 nop (mov r0,r0)
00000010 :
10:e1a00000 nop (mov r0,r0)
14:00000010 andeq r0, r0, r0, lsl r0
首先很顯然,ldr獲取的是記憶體的值(至於這個記憶體存的是資料還是位址,這個不是問題的重點,先不討論),像指標一樣間接定址(
看到了符號咯)
而adr是得到了乙個與pc有關的值,必定是個位址,韋老師舉了個例子:
adr r0, _start
時,r0就是_start對應的指令當前的位址
對於「_start
對應的指令當前的位址
」,我理解了很久,終於想清楚,比如在uboot中,_start標號對應的指令(即b reset這條指令)的鏈結位址是0x33f80000這個確鑿無疑。
如果從norflash啟動時,b reset被燒在norflash的0位址,那麼b reset相對於此時的pc來說,它的位址就是0;
所謂「當前
」是以執行時的pc為參照。
下面基於以上理解,分析一下test_adr.dis
00000000 <_start>:
0: e59f0008 ldr r0, [pc, #8]; 10
4: e28f0004 add r0, pc, #4; 0x4
8: e59f0004 ldr r0, [pc, #4]; 14 <.text+0x14>
c: e1a00000 nop (mov r0,r0)
00000010 :
10:e1a00000 nop (mov r0,r0)
14:00000010 andeq r0, r0, r0, lsl r0 1
先分析第一條指令ldr r0,test別編譯成ldr
r0, [pc, #8],也就是到當前pc+8的儲存器取值,當執行第一條指令時,pc其實已經是8了(流水線決定的)
那麼8+8就等於0x10,所以r0就等於e1a00000,這條指令的作用就是讀取test位址處存放的值。由於此處放了一條nop,那麼就是得到了nop的機器碼而已 2
第二條adr r0,test被編譯成add r0, pc, #4
這顯然是依賴程式執行到此處時的pc值了。
adr是小範圍的位址讀取偽指令.adr 指令將基於pc 相對偏移的位址值讀取到暫存器中
此指令在4位址,pc就是4+8=0xc再加4,於是r0=0x10
從結果上來看,test自身的值(標號值),被讀到了r0,這個值是以pc為參考的,也就是test對應的指令(第二個nop)當前的位址。
r0=(標號test 的位址與此指令的距離差)+(此指令的位址)=((0x10-0x4=12)+(4))=16=0x10
假如是在0x30000000以上執行,r0=((12)+(0x30000004))=0x30000010
3 ldr r0,=test
被編譯成兩個字,乙個指令,乙個文字池。執行到這裡pc=8,8+8+4=0x14.所以是在14位址取值,編譯器放在14位址處放了0x00000010,0x00000010就是test的值,假如在makefile裡指定連線位址是0x30000000,那麼編譯器放在這裡的就是0x30000010了,可見,這個值是編譯時確定的
andeq
r0, r0, r0, lsl r0
這個東西大概是編譯器的機械動作,把乙個數字也翻譯成了指令
adr,ldr指令的區別
首先來看一段指令和它的彙編結果 area test,code,readonly entry ldr r0,start adr r0,start ldr r0,start nop start nopend 彙編結果如下圖 首先,當執行第一條指令時,pc的指向是0x8008 start的值是0x8010...
int指令理解
以下是王爽老師的 組合語言 中第十五章中的一段程式 其功能是增加9號中斷的功能,當按下esc鍵時螢幕中顯示的字母改變顏色 assume cs codesg,ss stack,ds data data segment dw 0,0 data ends stack segment db 128 dup ...
arm彙編指令理解
blx指令 76 09 00 fa fa 00 09 76 31 30 29 28 27 26 25 24 23 0 1 1 1 1 1 0 1 0 h 0 000 0000 0000 1001 0111 011 0 最高4位表示執行條件 1111無條件執行 101固定指令碼 h 0signed i...