ARM組合語言入門
序言
看到一個比較好的ARM彙編入門教程。上不了班,閒著沒事翻譯了一下。
原址:
https://
azeria-labs。com/writing
-arm-assembly-part-1/
ARM 組合語言入門(一)
Part1:ARM彙編介紹
處理器arm VS。 intel
ARM與Intel有諸多不同,最主要的區別是指令集。Intel是
複雜指令集
(CISC:Complex Instruction Set Computing)處理器,擁有功能更多更豐富的指令,允許對記憶體進行更復雜的操作。因此也擁有更多的指令操作,定址模式,然而暫存器數量卻比ARM少。CISC處理器主要應用在個人電腦,工作站,伺服器當中。
ARM是
精簡指令集
(RISC:Reduced Instruction set Computing)處理器,擁有更簡單的指令集(少於100個)和更多的通用暫存器。與Intel不同,ARM指令只操作暫存器,且只能使用Load/Stroe(取/存)命令來讀取和寫入記憶體。也就是說,如果增加某個地址處的32位資料的值,你起碼需要三個指令(取,加,存):首先將該地址處的資料載入到暫存器(取),然後增加暫存器裡的值(加),最後再將暫存器裡的值儲存到原來的地址處(存)。
精簡指令集有優點也有缺點。優點之一是單條指令執行更快,相應地也獲得了更高的處理速度(精簡指令集系統透過減少單條指令的時鐘週期來減少執行時間)。不利的一面是更少的指令意味著更加要求更加註重軟體書寫效率。還要注意的是ARM有兩種工作狀態:ARM模式和Thumb模式。Thumb模式指令可以是2個位元組或者4個位元組(詳見Part 3:ARM指令集)。
ARM與x86其他區別:
ARM中大部分指令都可以用作條件執行。
x86和x86-64系列處理器使用
小端
(little-endian)地址格式。
ARM架構在第三版以前是小端模式。之後變為
大-小端
(BI-endian)格式,允許大端或小端兩種模式進行切換。
不僅ARM與Intel有不同,而且ARM各版本之間也有不同。本教程儘量保留它們之間最通用的部分以便你能理解ARM是怎麼工作的。一旦你理解了最基本的部分,當你選擇不同的ARM版本時也可以融會貫通。本教程所有的例子是在32-bit ARMv6平臺(Raspberry Pi 1)建立,所有的說明都是基於此版本。
不同ARM版本命名
ARM彙編
在開始ARM開發之前我們需要先了解基本的彙編程式設計。使用一般的程式語言或者指令碼語言來開發不行嗎,為什麼還需要ARM彙編?確實不行,如果我們要做逆向工程或者想了解ARM二進位制程式流,建立自己的ARM殼程式(shellcode:利用程式漏洞而執行的程式碼),手工製作ROP(Return-Oriented Programming一種利用特殊返回指令不斷返回多個前一段指令而最終拼成一段有效邏輯程式碼,以達到特殊攻擊目的的程式設計技術)工具鏈以及除錯ARM程式就要了解ARM彙編。
你不需要了解逆向工程或應用開發方面所有的組合語言細節,你只需要瞭解一個大概。基礎的知識都會在本教程中講到,如果你想要了解更多可以參考文末的附加連結。
那麼究竟什麼是組合語言?組合語言你可以看成是包裹在機器碼上的的一層薄薄的語法糖指令,這些指令代表著只有機器(計算機)才能讀懂的二進位制碼。那麼為什麼不直接寫機器碼呢?好吧,如果那樣做的話你絕對會很蛋疼。所以你最好還是寫彙編,人能夠容易讀懂的ARM彙編。計算機不能執行彙編程式碼,它只能讀懂機器碼。我們要使用工具來將彙編程式碼轉換為機器碼。GNU彙編器
as
為我們提供了這樣的功能,可以識別*。s型別的原始碼檔案。
當你編寫完副檔名*。s的彙編原始檔後,要用
as
編譯然後用
ld
連結:
$ as program。s -o program。o
$ ld program。o -o program
探秘組合語言
現在我們從最底層的工作做起。在最底層是電路板上的電訊號,電訊號是切換兩個不同的電平產生的,0V(off)或者5V(on)。因為很容易地看到電路的電平變化,所以我們可以透過視覺化數字0和1的表示來匹配電壓的開關模式,不僅是因為0/1可以代表電訊號的缺失和出現,還因為0/1是二進位制系統裡數字。然後用一系列0/1組成機器碼指令在計算機處理器中執行。下面就是一個機器語碼指令。
1110 0001 1010 0000 0010 0000 0000 0001
很好,但是我們難以記得這些0/1組合的代表什麼意思。因此我們使用叫做助記符的東西來幫助我們記憶這些二進位制組合,每個二進位制機器碼給定一個名字。這些助記符通常包含三段字元,但不全是。這種程式被叫做組合語言程式,它使用一系列助記符代表計算機機器碼。指令中的
運算元
放在助記符之後。例如:
MOV R2, R1
現在我們知道了彙編程式是由叫做助記符的文字資訊組成的,我們需要把它轉換為機器碼。前面提到的,GNU Binutils專案為我們提供了叫做
as
的彙編工具。使用
as
把ARM組合語言轉換為ARM機器碼的過程就叫做彙編。
綜上,計算機能夠理解(迴應)電訊號的缺失和出現,並且我們可以將這一系列電訊號表示成一組0/1序列(bits)。我們就可以用機器碼(一系列電訊號)讓計算機根據一種定義好的行為做出反應。因為我們難以記憶這一串0/1組成的指令的意義,所以提供了一種助記來代表這些指令。這組助記符是計算機的組合語言,我們使用名為“彙編器”的程式將程式碼從助記符表示形式轉換為計算機可讀的計算機程式碼,就像編譯器對高階語言程式碼做的一樣。
擴充套件閱讀
Whirlwind Tour of ARM Assembly。
https://www。
coranac。com/tonc/text/a
sm。htm
ARM assembler in Raspberry Pi。
http://
thinkingeek。com/arm-ass
embler-raspberry-pi/
Practical Reverse Engineering: x86, x64, ARM, Windows Kernel, Reversing Tools, and Obfuscation by Bruce Dang, Alexandre Gazet, Elias Bachaalany and Sebastien Josse。
ARM Reference Manual。
http://
infocenter。arm。com/help
/topic/com。arm。doc。dui0068b/index。html
Assembler User Guide。
http://www。
keil。com/support/man/do
cs/armasm/default。htm
上一篇:有沒有讓你一眼淪陷的動漫人物?