Arm入門第三講 Arm指令集學習
一丶Arm指令集
1.1 Arm指令集特點
-
1.所有指令都是定長的: 4個字節以內 x86指令是變長的可以很長很長.
-
2.大部分指令都可以在一個時鍾周期內完成.這比x86好多了 x86為了優化指令周期才會進行代碼優化
-
3.每一條指令都可以有條件執行. (ADD, ADDEQ QNLY IF Z=1)
這個條件執行大概是什么意思那. 意思就是ADD是進行加運算,這與x86一樣. 但是ADD后面可以加條件狀態比如EQ. 如果加了EQ那么他會先檢查狀態標志位中的Z位. 從而決定執不執行這條指令 這個是ARM匯編的特點
-
4.指令在通電之后可以配置為低位優先還是高位優先
-
5.LOAD/STORE 模型,專有指令才能訪問內存 這一點是ARM特點. x86基本大部門指令都可以直接訪問內存.ARM只能用這個.
1.2 流水線執行
流水線這個是CPU一個很重要的名字. 大概是什么意思那. 意思就是 把一條指令分成多個階段分別指令.
以x86匯編為例子
mov eax,10
add eax,11
mov ebx,12
add ebx,13
可以看到 指令是從上往下執行的. 第二條指令需要依賴於第一條指令的結果. 這樣就會導致效率很慢.
但是觀看指令我們就可以優化為下面的指令
mov eax,10
mov ebx,11
add eax,11
add ebx,12
這樣 第二條匯編就不依賴與第一條匯編指令了. 這就算是簡單的優化了. 而流水線不只是這些. 那么下面就說下需要了解的名次把.
-
Arm 使用的是三級流水線. 來加快指令的處理速度.
流水線技術可以使得多個操作**同步進行** 記住是同步進行. 而不是 **串行進行.** 試想一下,如果我們的第二條匯編依賴於第一條匯編的結果.那么是不是就必須等待第一條匯編執行完畢才能執行. 如果是這樣就不可以同步執行了.
Arm三級流水線 分別是 取址(fetch) 譯碼(decode) 執行(execute) 而在ARM匯編中.它的R15寄存器 也就是PC寄存器 執向的就是 fetch指令
-
x86則使用五級流水線
分別就是 取址(fetch) 譯碼(decode) 轉址(translate)執行(execute)寫回(wb)
二丶Arm指令格式(重要)
2.1 Arm Opcode
在x86下指令格式有x86形式. Arm同樣也有自己的指令格式. 知道指令格式可以編寫反匯編調試器等.
當然如果不寫的話那么學習Arm也要了解指令格式.
首先在32位下有如下圖:
總共 32位. 其中這里介紹下什么意思
Condition : 是用來存放我們條件碼的. 比如AddEQ 后面的EQ就是條件 NE等...
I 他不會在指令之中,他表示第二操作數的類型標志碼, 因為我們無法確定第二操作樹的類型
Opcode 位於第21-24位之間(4位) 是用來存放我們的操作碼 比如他們的助記符 Add Mov
S =1 表示是否影響我們的CPSR寄存器. 也就是比如MOVS 那么就會影響
Rn 表示第一源寄存器,表示是要從這個寄存器中取數據給RD的 ADDS R0,R1,R2 那么R1就是這里表示的,第一操作數的意思
Rd 表示目的寄存器,是用來存放我們的結果的
Operand2 表示第二操作樹的,RN表示第一操作數,他可以有多種形式,可以是立即數 可以是寄存器. 也可以是寄存器加移位,如: MOVS R3,R1 LSL #2
特殊:
BL W W不在指令中.這個只是指令寬度的說明符. 不會影響指令的行為 比如單獨寫 bl 那么又可能是16位的,也可能32位.
而我們Keill反匯編的時候 BLW則表示32位. 單獨的bl則是16位
Operand2 疑問:
第二操作數,大小是0-11位表示. 如果是0-11位表示那么他如何能表示一個32位的數那? 是不是就不行了那?
Operand2如果是立即數那么必須是一個合法的立即數 這個立即數必須滿足循環右移偶數位 而你循環右移的次數則用operand這個操作數的高四位進行保存,其它八位就是一個常數(0-255),雖然這樣可以解決保存的數據很大,但是他表達的數也是有限的。所以必須滿足這個公式的立即數才是真正意義上的合法立即數。
公式為:
Immediate = imm ROR(2*循環移位次數) Imm為8位
如:
MOV R0,#4096 = 0X40 ROR(26)位
2.2 指令組成格式了解
指令組成格式看下圖:
上面說了指令格式中的意思. 那么這個就是指令格式組成了.
其中在這個圖中有很多 <> {} 那么分別說下什么意思把
<> 代表這一項是必須要有的. 而不是能省略的.
{} 代表是可選的就是說可以不要的.
比如有個指令為:
ADDS 那么ADD 就是Opcode 是必須要的 S代表是修改CPSR狀態的. 那么中間就把條件給省略了.
你也許看到過 ADDEQ 那么EQ就是帶有條件的.
2.3 I模式詳解
如果 I 模式為立即數方式
如果為立即數方式,那么看下圖
如果為立即數方式,那么我們的第二操作樹就按照上面進行解析. 拆分為 4 8組合.
也就是一個32位的數可以用這個12位進行表示. 但是這個32位數必須是由一個八位的常數,循環右移偶數位得到的.
其中循環右移的位數是由一個四位的二進制數的兩倍來進行表示的.
比如說我們有一個立即數為
4096 那么我們的八位數最高能表示0xFF(255)字節大小
2.4 指令的條件執行
有以下指令
ADD R0,R1,R2 這個就代表無條件執行 R0 = R1 + R2ADDEQ R0,R1,R2 這個就代表有條件的執行 if (zF == 1){R0 = R1 + R2} ZF = 1表示兩數相等 ZF = 0 表示NE不想等 EQ是相等的意思ADDS R0,R1,R2 這里后綴帶S 不會不是判斷條件執行而是設置. R0 = R1 + R2 然后SET CPSR 中的ZFlag位
好處:
指令更加精簡了. 看如下代碼(不懂沒關系)
CMP R3,#0 比較R3與立即數0BEQ Skip 如果相等則跳轉到skip標簽執行ADD R0,R1,R2 這里就是如果不想等則會執行 R0 = R1 + R2Skip: 這是標簽
第二個程序
CMP R3,#0 同上ADDNE R0,R1,R2 在ADD同時帶上條件. 如果不想等 R0 = R1 + R2
所以觀看兩種匯編代碼.發現第二種更簡潔.且更好看.
ARM指令后面都可以跟上條件碼,下面就是收集的條件碼