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 執行未定義指令會引發未定義的異常。程序員可以利用指令異常完成相應的異常處理