對于指令和偽指令來說,很多人都有疑惑,他們到底是什么,有什么區別嗎,今天大神就來告訴你
1、指令(重點)
數據處理
單寄存器讀寫
ldr, ldrb, ldrh,
str, ...
前索引,后索引,自動索引
分支
b
bl // 自動把下一條指令的地址放到lr中移位
lsl, lsr, asr, ror, rrx
桶形移位器
對第二個操作數才有
2、立即數(重點)
8位的二進制數右移偶數位(0~30)能夠表示出來就是合法的
指令中的立即數是由一個 8 bit 的常數移動 4 bit 偶數位(0, 2,4, …, 26, 28, 30)得到的。所以,每一條指令都包含一個 8 bit 的常數 X 和移位值 Y,得到的立即數=X 循環右移(2×Y)
3、GNU的偽指令
.byte .short .long .word
.text .data
.global / .globl
.if .else .endif
.end
.align
.equ
4、指令解碼
編碼格式中各域含義如下。
:確定具體指令。
S:標識指令是否影響程序狀態寄存器 CPSR 條件標志。
Rd:指令操作的目的寄存器。
Rn:指令第一源操作數。
bit[11∶0]:移位操作,詳見本章移位操作一節。
bit[25]:被用來區分是立即數移位操作還是寄存器移位操作。如果指令編碼出現下面情況: bit[25] = 0 并且 bit[4] = 1 并且 bit[7]
= 1,則指令并非數據處理指令,它可能是 Load/Store 指令或算術指令。
1、機器碼
E3A0100C
1110 0011 1010 0000 0001 0000 0000 1010
Rd:表示寄存器編號0-15
注意:12bit表示立即數,有輪回規則20bit,S表示是否影響cpsr寄存器標志位2、
E1A01102
1110 0001 1010 0000 0001 0001 0000 0010
3、分支指令
0-23bit位一共24bit位,相當于FFFFFF,地址一共32位組成(0-
31),每個指令4個字節,[1:0]兩bit位始終為0,所以B指令偏移量能表示的范圍為FFFFFF*4,所以B指令跳轉的范圍為64M,由于可以向前向后跳,所以B指令的跳轉范圍為+-32Mbyte
4、 加s影響標志位
adds無進位cpsr的c位置0,有進位置1 subs無借位cpsr的c位置1,有借位置0 5、桶型移位器
Lsl不會影響cpsr標志位,lsls會影響對應標志位
移位的位數可以用立即數表示,但是是5位的立即數5位?2的5次方31(0-31),而寄存器32bit長,所以最多移動32-1位。
Lsl,lsls,asr,ror,rrx如果不加S,不影響標致位加S影響標志位,講義上是加s的圖示
6、 立即數
12位立即數中0-7表示立即數,8-11表示輪換規則。每次輪換2bit位,有連續24個0
7、 數據池
Ldr偽指令本質是通過ldr匯編指令實現
通過pc值加上一個偏移量得到一個地址,然后將地址中的值給寄存器,編譯器會將ldr偽指令的數編譯到程序的某一位置,存放這些常量的位置成為數據池
8、前索引、后索引
前索引(自動更新基址寄存器)先加后寫,++i 先移地址在寫值后索引,先寫入后加,i++ 先寫值后移地址