adr,ldr指令的區別

2021-09-03 02:13:03 字數 1476 閱讀 9057

首先來看一段指令和它的彙編結果:

area test,code,readonly

entry

ldr r0,_start

adr r0,_start

ldr r0,=_start

nop_start

nopend

彙編結果如下圖:

首先,當執行第一條指令時,pc的指向是0x8008

_start的值是0x8010,相差為8,所以,ldr指令是將通過這個差值來尋找,載入的是資料,不是位址值。

執行第二條指令時,pc指向0x800c,跟_start指令相差為4,所以這個adr指令也是通過差值來尋找。

r0=當前pc值加上(算出來的當前pc值和_start位址之間的差值)

當前pc值和_start位址之間的差值是已經確定的,當程式執行在不同的位址上,這個r0會隨之發生變化,但是

最終都會正確找到這個_start的位址值。

進行第三條指令分析之前,先來看一下偽指令,ldr r0,=start

這條指令在編譯的時候,會佔兩條指令的空間,因為通常ldr載入的不是乙個立即數,超出立即數的範圍,所以需要另外的32bit空間來儲存這個資料。

我們來看一下這條指令的編譯結果:

ldr r0 ,[pc,#0x0004]

(即使pc發生變化,只要使得pc+04這個位址中的資料,也就是r0實際的值,也就是_start的值確定下來,那麼r0就不會發生變化)

是這個位址中儲存的資料就是_start的位址,

首先,看一下當前的pc值是0x8010,加上4之後為0x8014,而在0x8014位置中儲存的是0x8010這個資料

而0x8010這個資料就是_start的數值,所以,可以說0x8014這個位址中儲存的就是_start這個資料,也就是ldr偽指令

這也就是說無論pc執行在哪個位址空間,ldr中的r0的值永遠不會發生變化。

文字池所佔得第二個空間位址。

第一點注意:pc值比當前執行指令值大8

第二點注意:實際上,ldr r0,=_start可以轉化為:

ldr      rn, [pc, #offset to literal pool] 的形式,直接去文字池所在的位址去找到這個位址。

且對於ldr偽指令,這個偏移範圍在arm狀態下<4kb,且這個偏移的方向可以向前可以向後

在thumb狀態下,這個偏移範圍<1kb,且只能向前偏移。

第三點注意:adr指令通常轉化為乙個add或者sub指令

可以載入的偏移位址的範圍

在字對齊的情況下,是不超過+-255bytes,在非字對齊的情況下是不超過+-1020bytes

這裡要求的都是字對齊,arm中字是32位。

而對於adrl指令,它的跳轉範圍更大一點:

當字不對其的情況下是+-64kb,當字對齊的情況下是+-256kb,且沒有在thumb情況下使用

理解adr,ldr指令

在閱讀u bootstart.s時,對adr和ldr指令有些疑惑,經韋老師指點,在參閱了一些網上的博文後,做了這個實驗 參照韋老師的 和makefile寫了 test adr.s text globl start start ldr r0,test adr r0,test ldr r0,test n...

指令和偽指令的區別

這個標題看似簡單,但是我卻一下子沒明白,這裡做下記錄。指令 每一條指令語句在源程式彙編時都要產生可供計算機執行的指令 即目標 所以這種語句又叫做可執行語句,每一條指令語句表示cpu具有的乙個基本能力,比如資料傳送,兩數相加或相減,移位等,而這種能力是在目標程式執行時完成的,是依賴於cpu 儲存器 i...

ARM指令和THUMB指令的區別

arm處理器的工作狀態 在arm的體系結構中,可以工作在三種不同的狀態,一是arm狀態,二是thumb狀態及thumb 2狀態,三是除錯狀態。嵌入式系統開發與應用教程 第2版 上介紹說 有兩種狀態arm狀態和thumb狀態,當時初學甚為不解,現在一知半解時再看忽然想到了顯示中的例子 arm核就好比乙...