因为毕设需要,接触了 ARM 指令集。记录一下。
<opcode>{<cond>} {S} <Rd>,<Rn>{,<opcode2>}
- <>为必须项
- {}为可选项
- <opcode>为指令,必须项,如 LDR, STR
- {<cond>}为指令执行条件,可选项, 如EQ, NE
- {S} 是否影响CPSR寄存器的值,不写则不影响
- Rd 目标寄存器
- Rn 第一个操作数的寄存器
- opcode2 第二个操作数
<opcode>
BIC
BIC指令的格式为: BIC{条件}{S} 目的寄存器,操作数1,操作数2。
BIC指令用于清除操作数1的某些位,并把结果放置到目的寄存器中。
操作数1应是一个寄存器, 操作数2可以是一个寄存器、被移位的寄存器、或一个立即数。
操作数2为32位的掩码,如果在 掩码中置了某一位1,则清除这一位。未设置的掩码位保持不变。
BIC R0, R0, # 0x1F ; (0x1F = 00011111 b),清除 R0 中的 bit[4:0] 位。
EOR
逻辑异或指令
EOR R0, R0, #3 ; 反转 R0 中的位 0 和 1
EOR R0, R0, #0x0F ; 将 R0 的第四位取反
MUL
乘法指令
MUL R1, R2, R3 ; R1 = R2 X R3
RSB
逆向相减指令
RSB R0, R1, R2 ; R0 = R2 -R1
ORR
或运算
ORR R0, R0 ,#3 ; R0 = R0 | 3
AND
与运算
AND R0, R1, R2 ; R0 = R1 & R2
MLA
乘-累加指令
MLA R1, R2, R3, R0 ; R1=R2×R3+R0
TST
位测试指令,检查是否设置了特定的位。操作数 1 是要测试的数据字而操作数 2 是一个位掩码,TST指令将操作数1与操作数2做逻辑与运算,和ANDS的区别就是不保存结果
注意 :与掩码逻辑与运算之后,全部测试位为0的时候,标志位Z = 1,此时EQ成立,反之则 Z = 0,NE成立。
TST R0, #1 ; 把 R0 与 1 位测试
CMN
CMN R0, #1 ; 把 R0 与 -1 比较
MOV
MOV R0, #3 ; 常数 3 传输到 R0 中。
MOV R0, R1 ; R1 的数据传输到 R0 。
MOV R1, R3, LSL, #3 ;将R3的数据 (R3)x8 存入 R1 中。
MOV PC, LR ;当 PC 为目标寄存器时,可以实现程序的跳转。
MVN
MVN R0, #3 ; 常数 3 取反再传输到 R0 中。
MVN R0, R1 ; R1 的数据取反传输到 R0 。
MVN R1, R3, LSL, #3 ;将R3的数据 (R3)x8 取反存入 R1 中。
MVN PC, LR ;当 PC 为目标寄存器时,可以实现程序的跳转。
LDR
LDR R0,[R1] ;将存储器地址为R1的字数据读入寄存器R0。
LDR R0,[R1,R2] ;将存储器地址为R1+R2的字数据读入寄存器R0。
LDR R0,[R1,#8] ;将存储器地址为R1+8的字数据读入寄存器R0。
LDR R0,[R1,R2] ! ;将存储器地址为R1+R2的字数据读入寄存器R0,并将新地址R1+R2写入R1。
LDR R0,[R1,#8] ! ;将存储器地址为R1+8的字数据读入寄存器R0,并将新地址R1+8写入R1。
LDR R0,[R1],R2 ;将存储器地址为R1的字数据读入寄存器R0,并将新地址R1+R2写入R1。
LDR R0,[R1,R2,LSL#2]! ;将存储器地址为R1+R2×4的字数据读入寄存器R0,并将新地址R1+R2×4写入R1。
LDR R0,[R1],R2,LSL#2 ;将存储器地址为R1的字数据读入寄存器R0,并将新地址R1+R2×4写入R1。
LDRB
操作的字节数据为源寄存器的低字节
LDRB R0,[R1] ;将存储器地址为R1的字节数据读入寄存器R0,并将R0的高24位清零。
LDRB R0,[R1,#8] ;将存储器地址为R1+8的字节数据读入寄存器R0,并将R0的高24位清零。
LDRH
操作的半字数据为源寄存器的低半字
LDRH R0,[R1] ;将存储器地址为R1的半字数据读入寄存器R0,并将R0的高16位清零。
LDRH R0,[R1,#8] ;将存储器地址为R1+8的半字数据读入寄存器R0,并将R0的高16位清零。
LDRH R0,[R1,R2] ;将存储器地址为R1+R2的半字数据读入寄存器R0,并将R0的高16位清零。
STR
STR R0,[R1],#8 ;将R0中的字数据写入以R1为地址的存储器中,并将新地址R1+8写入R1。
STR R0,[R1,#8] ;将R0中的字数据写入以R1+8为地址的存储器中。
STRB
操作的字节数据为源寄存器的低字节
STRB R0,[R1] ;将寄存器R0中的字节数据写入以R1为地址的存储器中。
STRB R0,[R1,#8] ;将寄存器R0中的字节数据写入以R1+8为地址的存储器中。
STRH
操作的半字数据为源寄存器的低半字
STRH R0,[R1] ;将寄存器R0中的半字数据写入以R1为地址的存储器中。
STRH R0,[R1,#8] ;将寄存器R0中的半字数据写入以R1+8为地址的存储器中。
STM
STMFD SP!, {R0} ;把R0保存到堆栈(sp指向的地址)中。
LDM
LDMFD SP!, {R0, R1, R2} ;把sp指向的3个连续地址段(应该是3*4=12字节(因为为r0,r1,r2都是32位))中的数据拷贝到r0,r1,r2这3个寄存器中去。
<cond>
EQ
- 条件 : 相等
- 标志位 : Z == 1
NE
- 条件 : 不相等
- 标志位 : Z == 0
CS/HS
- 条件 : 进位,无符号数高于或相等
- 标志位 : C == 1
CC/L0
- 条件 : 未进位,无符号数低于
- 标志位 : C == 0
MI
- 条件 : 负数
- 标志位 : N == 1
PL
- 条件 : 非负数
- 标志位 : N == 0
VS
- 条件 : 溢出
- 标志位 : V == 1
VC
- 条件 : 未溢出
- 标志位 : V == 0
HI
- 条件 : 无符号数大于
- 标志位 : C == 1 && Z == 0
LS
- 条件 : 无符号数小于等于
- 标志位 : C == 0 || Z == 1
GE
- 条件 : 带符号数大于等于
- 标志位 : N == V
LT
- 条件 : 带符号数小于
- 标志位 : N != V
GT
- 条件 : 带符号数大于
- 标志位 : Z == 0 && N == V
LE
- 条件 : 带符号数小于等于
- 标志位 : Z == 1 && N != V
AL
- 条件 : 无条件执行
- 标志位 : -
NV
- 条件 : 从不执行
- 标志位 : -
移位操作
LSL
逻辑左移,将操作数向左移位,低位补零,移除的高位进行丢弃
MOV R1, R0, LSL #2 ; r1 = r0 << 2
ASL
算术左移,将操作数向左移位,低位补零,移除的高位进行丢弃
LSR
逻辑右移,将操作数向右移位,高位补零,移除的低位进行丢弃
ASR
算术右移,将操作数向右移位,高位补零,移除的低位进行丢弃
ROR
循环右移,将操作数向右移位,移除的低位补高位
寄存器
r0~r3
子程序间传递参数
r4~r11
保存局部变量
Thumb 程序中,使用 r4~r7保存局部变量
r12
子程序间 scratch 寄存器,即 ip 寄存器
r13
栈指针,即sp
r14
连接寄存器(lr),保存子程序及其中断的返回地址
r15
程序计数器(pc)
正确读取了 PC 的值后,该值为当前指令地址加 8 个字节,即 PC 指向当前指令的下两条指令地址
赞一个