arm汇编指令:ldr和adr的区别
在分析uboot源碼時(shí),遇到adr、ldr指令,卻分不清這2者的區(qū)別,網(wǎng)上很多解釋含糊不清,現(xiàn)對(duì)adr與ldr指令做解釋。
首先給出一段匯編代碼:
ldr r0, _startadr r0, _startldr r0, =_startnopmov pc, lr _start:nop設(shè)置代碼的起始地址為?0x0c008000,用 ADS1.2編譯后的反匯編如下所示:
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, lr0c008014 <_start>: c008014: e1a00000 nop (mov r0,r0) c008018: 0c008014 stceq 0, cr8, [r0], -#80分析:?
1、ldr???? r0, _start;
這里ldr是一個(gè)指令,把內(nèi)存地址 _start(0c008014)對(duì)應(yīng)的值(可能是數(shù)據(jù)或指令對(duì)應(yīng)的機(jī)器碼)讀入。執(zhí)行這個(gè)后,r0 = 0xe1a00000。
2、adr???? r0, _start;小范圍的地址讀取偽指令
adr是一個(gè)偽指令,通過指令“add? r0, pc, #8?”把_start標(biāo)號(hào)對(duì)應(yīng)的地址加載到 r0,因?yàn)榈刂肥窍鄬?duì)程序的,因此adr產(chǎn)生依賴于位置的代碼。這里這段代碼在 0x0c008000 運(yùn)行,那么 adr r0, _start 得到 r0 = 0x0c008014;如果在地址 0 運(yùn)行,那么r0 = 0x00000014。
通過這條偽指令就可以得知當(dāng)前程序在內(nèi)存的什么位置運(yùn)行。這是一條偽指令,但是功能卻如此強(qiáng)大,需要相應(yīng)的編譯器功能才能實(shí)現(xiàn)。
3、ldr???? r0, =_start;大范圍的地址讀取
這里ldr是一個(gè)偽指令,用于加載32位的立即數(shù)或一個(gè)地址值到指定寄存器。這條指令取得的是標(biāo)號(hào)_start 的絕對(duì)地址。這個(gè)絕對(duì)地址是在編譯器編譯完后進(jìn)行?link(鏈接)的時(shí)候確定的??瓷先ミ@只是一個(gè)指令,但是它要占用 2 個(gè) 32bit 的空間,一條是指令,另一條是 _start 的數(shù)據(jù)(因?yàn)樵诰幾g階段不能確定 _start 的值(要等到link時(shí)才確定),而且也不能用 mov 指令來給 r0 賦一個(gè) 32bit 的常量,所以需要多出一個(gè)空間存放 _start標(biāo)號(hào)對(duì)應(yīng)的地址數(shù)據(jù),這里就是 0x0c008014,r0=0x0c008014)。
參考:
https://www.cnblogs.com/amanlikethis/p/3419710.html?
https://www.cnblogs.com/jack739x/articles/2060762.html
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的arm汇编指令:ldr和adr的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ARM七种模式理解
- 下一篇: arm汇编:.balignl伪指令理解