对于指令和伪指令来说,很多人都有疑惑,他们到底是什么,有什么区别吗,今天大神就来告诉你
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++ 先写值后移地址