ARM彙編基礎教程——ARM指令集

ARM和Thumb

ARM處理器有兩種工作狀態ARM和Thumb(Jazelle此處先不考慮)。這兩種工作狀態和運行模式沒有任何關係。比如不論是ARM還是Thumb狀態的代碼都可以運行在用戶模式下。這兩種工作狀態之間最大的差異是指令集,ARM狀態的指令長度是32位的,Thumb狀態的指令長度是16位的(也可能為32位)。了解如何使用Thumb工作狀態對於編寫ARM平台的漏洞利用是至關重要的。當我們編寫ARM shellcode時,需要使用16 bit的Thumb指令代替32 bit的ARM指令,從而避免在指令中出現』』截斷。

容易引起混淆的是,不同的ARM版本,支持的Thumb指令集並不相同。在某些版本中,ARM引入了擴展的Thumb指令集(也就是Thumb-2),它支持32 bit指令以及條件執行。這在原本的Thumb指令中都是不受支持的。為了在Thumb狀態下支持條件執行,「it」指令被引入。然而,可能是為了簡化指令集,這個指令在後來的版本中被刪除了。我認為這種設計反而增加了兼容的複雜度。不過,當然我認為沒必要知道所有ARM版本的ARM/Thumb指令集變體,我建議你也不必在這上面浪費太多時間。你只需要知道目標設備的版本和該版本對Thumb指令有哪些特殊支持,然後調整你的代碼就好了。ARM Infocenter可以幫助你了解各個ARM版本的具體細節(http://infocenter.arm.com/help/index.jsp)。

我們已經知道了Thumb有不同的版本,下面我們對不同的版本做一下簡單的介紹,注意不同的命名只是為了區分不同的版本(換句話說,處理器只知道它運行在Thumb狀態,其它一概不知)。

  • Thumb-1(16位指令):用於ARMv6和更早的版本。
  • Thumb-2(16位和32位指令):對Thumb-1的擴展,添加了更多指令並允許它們為16位或32位寬(ARMv6T2,ARMv7)。
  • ThumbEE:在Thumb-2基礎上包含了針對動態代碼生成(代碼在執行前或執行期間編譯代碼)的一些變更和補充。

ARM和Thumb的區別:

  • 條件執行:ARM狀態下的所有指令都支持條件執行。某些ARM處理器版本允許使用IT指令在Thumb中進行條件執行。條件執行提高了代碼密度,因為它減少了要執行的指令數量,並節省了昂貴的分支指令。
  • 32位ARM和Thumb指令:32位Thumb指令具有.w後綴。
  • 桶形移位器是另一種ARM模式特有的功能。它可以將多個指令合併成一個。例如,您可以通過使用如下指令(將移位包含在MOV指令內)左移1位「Mov R1,R0,LSL#1; R1 = R0 * 2」從而代替兩個乘法指令(只用乘法指令將寄存器的值乘以2,並使用MOV將結果存儲到另一個寄存器中)。

要切換處理器的執行狀態,必須滿足以下兩個條件之一:

  • 我們可以使用分支指令BX(分支和狀態切換)或BLX(分支,返回和狀態切換),並將目標寄存器的最低有效位置1。這可以通過將1添加到偏移量(如0x5530+1)來實現。你可能會認為這會導致對齊問題,因為指令總是2或4位元組對齊的。然而,這麼做不會導致問題,因為處理器在讀取指令時是忽略最低有效位的。更多的細節將在第6篇:條件分支中介紹。
  • 如果當前程序狀態寄存器中的T位置1,我們知道我們處於Thumb模式。

ARM指令簡介

這一節的目的是簡要介紹ARM的指令集和它的基本用法。作為彙編語言的基本單位,了解指令的用法,指令間的如何關聯以及將指令進行組合能實現什麼功能對於學習彙編語言是至關重要的。

ARM彙編由ARM指令組成。ARM指令通常跟一到兩個操作數,我們使用如下模板描述:

MNEMONIC{S}{condition} {Rd}, Operand1, Operand2

需要指出的是,只有部分指令用到了指令模板中的所有域。模板中各欄位的作用如下所示:

MNEMONIC - 指令的助記符如ADD

{S} - 可選的擴展位

- 如果指令後加了S,將依據計算結果更新CPSR寄存器中相應的FLAG

{condition} - 執行條件,如果沒有指定,默認為AL(無條件執行)

{Rd} - 目的寄存器,存儲指令計算結果

Operand1 - 第一個操作數,可以是一個寄存器或一個立即數

Operand2 - 第二個(可變)操作數

- 可以是一個立即數或寄存器甚至帶移位操作的寄存器

助記符、S擴展位、目的寄存器和第一個操作數的作用很好理解,不多做解釋,這裡補充解釋一下執行條件和第二個操作數。設置了執行條件的指令在執行指令前先校驗CPSR寄存器中的標誌位,只有標誌位的組合匹配所設置的執行條件指令才會被執行。第二個操作數被稱為可變操作數,因為它可以被設置為多種形式,包括立即書、寄存器、帶移位操作的寄存器,如下所示:

#123 - 立即數

Rx - 寄存器比如R1

Rx, ASR n - 對寄存器中的值進行算術右移n位後的值

Rx, LSL n - 對寄存器中的值進行邏輯左移n位後的值

Rx, LSR n - 對寄存器中的值進行邏輯右移n位後的值

Rx, ROR n - 對寄存器中的值進行循環右移n位後的值

Rx, RRX - 對寄存器中的值進行帶擴展的循環右移1位後的值

最後我們來看一些滿足上述指令模板的常見指令,這些指令將會在後續的例子中出現。

本文由看雪翻譯小組 ljcnaix 編譯,來源Azeria Labs 轉載請註明來自看雪社區


推薦閱讀:

指令cache 為什麼比數據cache失效率低?
一文看懂ARM公司
ARM NEON 優化

TAG:ARM | 汇编语言 | ARM指令 |