1. 程式人生 > >ARM偽指令

ARM偽指令

體系結構 進行 可用 如果 arm指令集 編譯 反匯編 數據 初始化

1、偽指令是什麽

ARM偽指令不是ARM指令集中的指令,只是為了編程方便人們定義了偽指令。
在匯編時這些指令將會被等效的ARM指令或arm指令的組合代替。
編程時可以像其他ARM指令一樣使用偽指令,區別是偽指令不像指令一樣有對應的機器編碼。

我今天主要給大家介紹4條這樣的偽指令。其實還有與這四條偽指令形式類似但是作用完全不同的偽指令,他們主要是指導匯編器完成匯編工作,例如定義數據、分配儲存區、程序初始化。我們這四條偽指令的作用僅僅是用一條指令代替多條指令,方便編程

在給大家演示之前,我想給介紹一下我碰見的一個關於PC的問題

2、PC

程序計數器存放下一條要執行的指令的地址。

ARM(ARM7) 采用三級流水線結構,取指、譯碼、執行,PC始終指向你要取的指令的地址,而不是執行完一條指令後指向下一條指令的地址。

匯編器把R15(PC)這個顯示值進行了補償,使“PC指向下一條要執行的指令的地址”這個邏輯看起來合理。

3、ADR/ADRL

指令書寫格式:ADR(ADRL)[<cond>] <Rd>,<label>

將地址載入寄存器中。基於PC相對偏移的地址讀取到寄存器中。通常會被一條ADD或SUB指令替代實現相同功能。
ADR是小範圍地址讀取偽指令當地址值是字節對齊時,取值範圍為-255到255,當地址值是字對齊時,取值範圍-1020到1020
ADRL是中等範圍地址讀取偽指令當地址值是字節對齊時,取值範圍為-64KB到64KB,當地址值是字對齊時,取值範圍為-256KB到256KB。ADRL偽指令比ADR偽指令可以讀取更大範圍的地址,這是因為在編譯階段,ADRL偽指令被編譯器換成兩條指令。如果匯編器不能再兩條指令內完成操作,將報告錯誤,終止編譯。

ADRL 始終匯編為兩個 32 位指令。 即使使用單個指令就可完成地址訪問,也會生成多余的第二個地址。

4、LDR

指令書寫格式:LDR[<cond>][<.W>]<Rd>,<=expr>/<=label_expr>

由於編碼格式的限制,ARM在使用MOV指令時所能操作的立即數值範圍是有限的。為了編程方便可以使用LDR偽指令加載數值。
如果表達式expr的值能用一個MOV或MVN指令進行加載,那麽匯編器就使用MOV或MVN指令。
如果立即數由於超出了 MOV 和 MVN 指令的範圍,或者使用了label_expr,匯編器就把這個常量放在文字池裏然後使用一條PC相對形式的LDR指令從文字池裏讀取這個常量。

其一般指令LDR和宏指令LDR格式相似。處理為宏指令的情況中,指令是否有“=”為區別的關鍵

5、MOV32

指令書寫格式:MOV32 [<cond>] <Rd>,<expr>/<label_expr>

此指令只可用於ARMv6T2 及更高版本中的ARM和Thumb狀態
將數值或地址裝載到寄存器中,類似LDR

編譯器會將MOV32翻譯為movw和movt兩條指令。
MOVW會把16位立即數放到寄存器的底16位,並將高16位清0。
MOVT 會把16 位立即數放到寄存器的高16位,同時低16位不受影響。

6、UND

UND [<cond>][<.W>] <#expr>

生成無體系結構定義的指令。此偽指令生成的編碼將反匯編為 DCI
執行未定義指令會引發未定義的異常。程序員可以利用指令異常完成相應的異常處理

ARM偽指令