本文共 3898 字,大约阅读时间需要 12 分钟。
ARM常用汇编指令
3.1ARM v7处理器寄存器
CPSR(当前程序状态寄存器)
Condition flags, bits[31:28](在任意模式下可读可写) N, bit[31] Negative condition flag N = 1,表示运算为负值 Z, bit[30] Zero condition flag Z = 1,表示运算为0 C, bit[29] Carry condition flag C = 1,表示运算有借位 V, bit[28] Overflow condition flag. V = 1,表示符号位溢出 Q, bit[27] Cumulative saturation bit E, bit[9] Endianness execution state bit. Controls the load and store endianness for data accesses: 0 Little-endian operation 1 Big-endian operatio Mask bits, bits[8:6] These bits are: A, bit[8] Asynchronous abort mask bit. I, bit[7] IRQ mask bit. F, bit[6] FIQ mask bit. The possible values of each bit are: 0 Exception not masked. 1 Exception masked. M[4:0], bits[4:0] 控制处理器模式位1 Exception masked.
3.2 ARM汇编指令
MOV(把一个寄存器的值/立即数,赋值到另一个寄存器中)
MOV<c><Rd>, #<imm8> eg: movr1,#32
MOV{S}<c><Rd>, <Rm> eg: mov r1,r2
ADD(将一个寄存器的值/立即数和另一个寄存器的相加,放入目的寄存器中)
ADD{S}<c><Rd>, <Rn>, #<const> eg:add r2,r1,#32
ADD{S}<c><Rd>, <Rn>, <Rm>{, <shift>} eg: add r2,r2,r1(add r2,r1)
SUB(将一个寄存器的值和另一个寄存器/立即数的相减,放入目的寄存器中)
SUB{S}<c><Rd>, <Rn>, #<const> eg:sub r2,r1,#32
SUB{S}<c><Rd>, <Rn>, <Rm>{, <shift>} eg:sub r2,r1
MUL(将一个寄存器的和另一个寄存器的相乘,放入目的寄存器中)
MUL<c><Rd>, <Rn>, <Rm> eg:mul r3,r2,r0
LSL逻辑左移
LSL{S}<c><Rd>, <Rm>, #<imm5>
LSL{S}<c><Rd>, <Rn>, <Rm>
LSR逻辑右移
LSR{S}<c><Rd>, <Rm>, #<imm>
LSR{S}<c><Rd>, <Rn>, <Rm>
ASR算术右移
ASR{S}<c><Rd>, <Rm>, #<imm>
ASR{S}<c><Rd>, <Rn>, <Rm>
ROR循环右移
ROR{S}<c><Rd>, <Rm>, #<imm>
ROR{S}<c><Rd>, <Rn>, <Rm>
示例:
movr0,r1,lsl #3 r0 = r1*(2^3)
addr0,r1,r1,lsl #3 r0 = r1+r1*(2^3)
subr0,r1,r2,lsr #4 r0 = r1-r2/(2^4)
movr0,r1,ror r2 r0 = r1循环右移r2位
b(跳转指令)、bl(带返回的跳转指令)
Bb fun1
……
Fun1:
……
Bl fun2
Fun2:
……
两者的区别在于bl跳转后,将返回地址(bl的下一条指令的地址)保存在lr寄存器中。
mov lr,pc b fool 等价于 bl fool
--------------------------------------------------------------
--------1-------- ---------2--------
"movlr,pc\n\t"
"bfool\n\t" 等价于 "bl fool\n\t"
--------3-------- --------4---------
"movlr,pc\n\t" "mov lr,pc\n\t"
"ldrpc,=fool\n\t" 等价于 "ldr pc,fool_\n\t"
"nop\n\t" "bend\n\t"
"fool_:\n\t"
".word fool\n\t"
"end:\n\t"
-------------------------------------------------------------
MRS MSR状态寄存器(cpsr)访问指令
MRS<c> <Rd>, <spec_reg> eg:mrs r0,cpsr
将CPSR的值传送到寄存器中(读)
MSR<c> <spec_reg>, #<const>/<Rn> eg:msr cpsr,r0
将立即数/寄存器的值传送到CPSR中(写)
CMP比较指令
Rn - Rm/const 根据结果更新cpsr的标志位,下一条指令可根据cpsr标志位做出相应操作。
CMP<c> <Rn>, #<const>
CMP<c> <Rn>, <Rm>{, <shift>}
TST 位测试指令
Rn和Rm/const按位与,更新cpsr标志位
TST<c> <Rn>, #<const>
TST<c> <Rn>, <Rm>{, <shift>}
TEQ 相等测试指令
Rn和Rm/const相异或,更新cpsr标志位
TEQ<c> <Rn>, #<const>
TEQ<c> <Rn>, <Rm>{, <shift>}
LDR 从内存中读去数据到寄存器(ldr 32bit ldrb 8bit ldrh 16bit)
LDR<c> <Rt>, [<Rn>{, #+/-<imm12>}]
LDR<c><Rt>, [<Rn>], #+/-<imm12>
LDR<c><Rt>, [<Rn>, #+/-<imm12>]!
eg: ldr r1,[r2,#4] 将地址为r2+4的内存单元数据读取到r1寄存器中
ldr r1,[r2] 将地址为r2的内存单元数据读取到r2寄存器中
ldr r1,[r2],#4 将地址位r2的内存单元数据读取到r1寄存器,然后r2 = r2+4
ldr r1,[r2,#4]!将地址为r2+4的内存单元数据读取到r1寄存器中,同时r2=r2+4
STR把寄存器的值存储到内存中(str 32bit strb8bit strh 16bit)
STR<c> <Rt>, [<Rn>{, #+/-<imm12>}]
STR<c><Rt>, [<Rn>], #+/-<imm12>
STR<c><Rt>, [<Rn>, #+/-<imm12>]!
eg: str r1,[r2,#4] 把r1中的数据保存在地址r2+4的内存中
str r1,[r2],#4 把r1中的数据保存在地址r2的内存中
str r1,[r2],#4 把r1中的数据保存在地址r2的内存中,然后r2=r2+4
str r1,[r2,#4]!把r1中的数据保存在地址r2+4的内存中,同时r2=r2+4
ldm 从连续的内存读取数据,到寄存器列表中的各个寄存器中
stm 将寄存器列表中的各个寄存器中值写入到连续的内存中
LDM<c><address_mode> <Rn>{!}, <registers>
STM<c><address_mode> <Rn>{!}, <registers>
<address_mode>:
ia(increment after) 事后递增
ib(increment before) 事先递增
da(decrement after) 事后递减
db(decreament before) 事先递减
ARM汇编指令条件码如下图所示(<c>)。
3.3 APCS(ARM Procedure Call standard)规则
a.寄存器的使用规则
r0-r3 用于函数的传参,使用之前不用保存他的值,别名a1-a4
r4-r11用于保存函数内部的局部变量 别名 v1 -v8 使用之前保存他的值,使用之后恢复他的值,
r11 特别的别名fp
r12 别名ip
r13 别名sp栈指针寄存器,不能用于其他用途
r14 别名lr连接寄存器,用于保存子程序的返回地址,不能用于其他用途
r15 别名 pc 程序寄存器
b.栈的使用规则(满递减)
空栈,满栈 满递减 fd(full descending)
栈分为空栈和满栈,
满栈:sp指向最后一次入栈的数据所占的内存,先偏移后入 full
空栈:sp指向最后一次入转的数据的下一个内存,先入后偏移。
ascending 递增
descending 递减
stmfd ldmfd
stmdb ldmia
push pop
C.函数调用过程中参数的传递规则
行参前四个r0-r3 大于4个通过出栈传递
返回值32位 放到r0 64位 高32放r1 低32放r0