新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ARM編程進(jìn)階之一-ARM匯編偽指令

ARM編程進(jìn)階之一-ARM匯編偽指令

作者: 時間:2016-11-27 來源:網(wǎng)絡(luò) 收藏
到目前為止,我們已經(jīng)具備編寫較為復(fù)雜的ARM匯編程序的能力,但要編寫較為復(fù)雜且實(shí)用的程序,我們就不得不掌握ARM匯編的偽指令(pseudo-instruction)。千萬別把匯編偽操作(directive)與匯編偽指令(pseudo-instruction)弄混了,directive不會被編譯器編譯為機(jī)器指令,但pseudo-instruction會。而pseudo-instruction與指令(instruction)的區(qū)別在于,1條instruction與1條機(jī)器指令對應(yīng),而編譯器會把1條pseudo-instruction編譯為1條或多條機(jī)器指令。

ARM匯編偽指令共4條:ldr、adr、adrl、nop

本文引用地址:http://butianyuan.cn/article/201611/322178.htm

1、ldr

首先我們來回答“基本尋址模式與基本指令”一文中提出的問題。“如果我們需要mov r0, #10000這樣的指令,應(yīng)該怎么辦?(常數(shù)10000不能在機(jī)器指令32bit中的低12bit中被表示出來)”。當(dāng)你進(jìn)行編譯的時候,“Error:All70E”的錯誤就會出現(xiàn),如下圖。

其實(shí),這個問題很容易解決,只需要將mov r0, #10000換為ldr r0, =10000即可。為什么這樣就可以了呢?因?yàn)?,這里的ldr r0, =10000并非我們已經(jīng)學(xué)過的ldr指令,而是一條偽指令,編譯器會將這條偽指令替換為:

ldr r0, [pc, #-4]
DCD 10000

DCD所分配的內(nèi)存空間中存放了整數(shù)10000,該內(nèi)存空間被稱為literal pool,中文名稱“文字池”。由于整個程序都是由編譯器編譯的(包括文字池的分配),所以很顯然編譯器能夠知道ldr指令在內(nèi)存中的地址與文字池在內(nèi)存中的位置之間的偏移量,因此編譯器就可以正確地使用以pc為基址,采用相對尋址的ldr指令將文字池中的數(shù)取出加載到寄存器r0中。由此可見,編譯器對于ldr r0, =10000這條偽指令的處理,其實(shí)質(zhì)是:

在匯編源程序時,LDR偽指令被編譯器替換成一條合適的指令和存放常數(shù)的文字池。匯編器將常量放入文字池,并使用一條程序相對偏移的LDR指令從文字池讀出常量。

由于,4byte可以存放任何int型整數(shù),這樣一來,常數(shù)就可以是任何int型整數(shù),而不再受制于12bit的限制。當(dāng)然此時的常數(shù)是存放在內(nèi)存中的,而不是存放在機(jī)器指令的32bit編碼中的。

額外說明:

a)、ldr r0, [pc, #-4]中是-4,而不是+4,是由于流水線的原因(參見“流水線對PC值的影響”一文)。今后對于流水線的這種影響,我將不再予以特別說明。

b)、從指令位置到文字池的偏移量必須小于4KB

c)、從語法上來看,與ARM指令的LDR相比,偽指令LDR的參數(shù)有“=”號,沒有“#”號

d)、如果常數(shù)能夠被12bit表示出來,例如:ldr r0, =0x100,那么,編譯器對該偽指令的處理,是使用MOV(或者M(jìn)VN)指令代替該LDR偽指令,例如:mov r0, #0x100,而不會采用ldr指令+文字池的方式。

除了 ldr 寄存器, =常數(shù) 這種形式外,還有l(wèi)dr 寄存器, =標(biāo)號 這種形式也經(jīng)常被使用,下面我就來講解這種形式的ldr偽指令。

由上圖可見:ldr pc, =InitStack這條偽指令的作用是將標(biāo)號InitStack所代表的地址賦予pc。 這里會使我們產(chǎn)生幾個疑問:

a)、為什么不使用bl InitStack,而要使用ldr pc, =InitStack?

這是因?yàn)閎l指令的跳轉(zhuǎn)范圍是正負(fù)32M,而InitStack所代表的位置有可能距離ldr pc, =InitStack超過32M,此時bl就無能為力了。竟然存在這么大范圍跳轉(zhuǎn)的程序(這似乎意味著編譯出來的二進(jìn)制可執(zhí)行文件的大小會操作32M),這一點(diǎn)似乎令我們感到非常震驚。事實(shí)上是:大小超過32M的可執(zhí)行程序的確幾乎不可能出現(xiàn),但即使是很小的二進(jìn)制程序中也可能進(jìn)行大范圍(超過32M)的跳轉(zhuǎn),這一點(diǎn)在bootloader程序中幾乎是必然的。


上一頁 1 2 下一頁

評論


技術(shù)專區(qū)

關(guān)閉