(本篇内容可参考《ARM汇编手册》)
0. 注释
@后跟注释,作用范围是@开始,到本行结束
1. 算术与逻辑
1.1 mov {条件} <dest> <op1>
说明:相当于赋值,目的寄存器为通用寄存器,共32bit传递,其中12bit传递立即数(8bit为基数,4bit为移位数),因此,其立即数只能是8bit(重要)
举例:mov r0,r1 @ 把r1寄存器的值赋给目的寄存器r0
mov r0,#1 @把立即数1 赋给目的寄存器r0
mov r0,#0b0101 @把二进制立即数 0101赋给目的寄存器r0
mov r0,#0xff @把十六进制立即数 ff 赋给目的寄存器r0
1.2 mvn {条件} <dest> <op1>
说明:把<op1>按位取反后,丢进r0。用次指令很少注意其真值,作用只是把<op1>的值取反再赋值
举例:mvn r0,#4 @把立即数 4 取反后0xffff fffb丢进r0,而0xffff fffb的符号位为1,取反加 1 后,其真值为-5
mvn r0,#0b10 @把二进制立即数0b10,也就是 2 取反后 0xffff fffd丢进r0,同理,真值为-3
1.3 sub {条件} <dest> <op1> <op2>
说明:<op1>减去<op2>后的值放到<dest>中,而被减数<op1>不能是立即数,但减数<op2>可以为立即数,当然被减数和减数不能同为立即数
sub操作并不影响CPSR
举例:sub r0,r1,r2 @ r0 = r1 - r2
sub r0,r1,#3 @ r0 = r1 - 3 <op2>可以是立即数
sub r0,#4,r3 X @ <op1>不能是立即数
1.4 add {条件} <dest> <op1> <op2>
说明:<op1>加上<op2>后的值放到<dest>中,而被加数<op1>不能是立即数,但加数<op2>可以为立即数,当然被加数和加数不能同为立即数
和mov一样,<op2>若是立即数,那只能是8bit,但和mov不同的是add可以实现两个小于等于 0xff 的数相加后的赋值
举例:add r0,r1,#2 @r0 = r1 +1
add r0,r1,r2 @r0 = r1 + r2
add r0,#1,r2 X @<op1>不能是立即数
1.5 and {条件} <dest> <op1> <op2>
说明:用<op1>跟<op2>进行逻辑与运算,把结果丢到<dest>中,一般用于屏蔽寄存器的某些位,and操作并不影响CPSR
举例:and r0,r1,#0b10 @屏蔽除了第二位以外的其他位,使得其他位为0
1.6 bic {条件} <dest> <op1> <op2>
说明:用<op1>跟<op2>进行逻辑与运算,把结果丢到<dest>中,一般用于对某些位置 0 ,和and的区别是,<op2>中1为置 0 ,其他位保持原来
举例:bic r0, r1,#0b10 @把r1中的第二位致零,其他位保持原来值
2. 比较指令
2.1 cmp {条件} <op1> <op2>
说明:操作是用<op1> 减去<op2>,然后根据结果来影响CPSR中的N位和Z位的值
举例:cmp r1,r2 @若r1大于r2 r1 - r2 > 0 ,则 N 位置 0 ,Z 位置0
@若r1小于r2 r1 - r2 < 0 ,则 N 位置 1 ,Z 位置0
@若r1等于r2 r1 - r2 = 0 ,则 N 位置 0 ,Z 位置1
2.2 tst {条件} <op1> <op2>
说明:其实质就是执行<op1> and <op2>的操作,其结果将影响CPSR的Z位,若是结果为 0,则Z位置 1 ,表示要检查的位确实是 0
and和tst的主要区别是,and把两个寄存器按位与后,把结果保存到目标寄存器,但不影响CPSR,而tst会根据结果而影响CPSR
举例:mov r1,#0b101
tst r1,#0b010 @因为0b101 and 0b010 的结果位0,要检查的第二位确实是0,所以CPSR的Z位置 1
3. 跳转指令
3.1 b {条件} <地址>
一般用于通过cmp判断后由b来进行跳转,例如:
cmp r1,r2
bgt branch_1
add r3,r1,r2
b end
branch_1:
sub r3,r1,r2
end:
nop
把以上语句转变为C语言就是:
if( a > b)
c = a - b;
else
c = a + b;
b与ldr的主要区别是,b是先计算出当前PC与目标地址的相对偏移量,再进行PC 的移位;而ldr是直接跳转到目标地址的绝对移位。
3.2 bl 带链接地址返回的分支
说明:bl跳转前,把下一条要执行的指令的地址保存到 lr 中,当执行完跳转后的函数后,再执行mov pc,lr,返回原来的程序,例如:
mov r1,#1
bl fun
mov r2,#2
b fun_end
fun:
mov r3,#3
mov pc,lr
fun_end:
nop
是先把立即数1赋值给r1,然后跳转到fun去执行把立即数3赋值个r3的操作,在通过mov pc,lr回到原来的地方执行把立即数2赋值给r2,进最后跳转到b_end,
换成C语言大概就是:
r1 = 1;
fun();
r2 = 2;
fun()
{
r3 = 3;
}
4. 移位指令
4.1 lsl :算术左移,右边补0,例如:
mov r1, #0b1
mov r0, r1, lsl #2 ; r1左移2位后赋值给r0
4.2 ror : 循环右移,例如:
mov r1, #0b11
mov r0, r1, ror #1 ; 是把r1循环右移一位后,赋值给r0,但r1是不变的
5. 程序状态字访问指令(msr,mrs)
因为无法使用mov访问cpsr,只能通过msr和mrs来访问,例如:
mrs r0, cpsr
orr ro, #0b100
msr cpsr, r0
6. 存储器访问指令(ldr, str),例如:
mov r1, #0xcf
str r1, [r2]
ldr r0, [r2] ;[r2] 不能是立即数,不能没中括号!(重要)