1. 通用寄存器
r0 ~ r15
有特殊用途的寄存器:
r14:别名lr,保存函数返回地址
r15:别名pc, 程序计数器,值为当前指令地址+4(顺序执行的下一条指令)
与编译器有特殊约定的寄存器:
r13:别名sp,栈顶指针
(r9~r13都有约定,但还是sp最常用到)
其他与函数调用约定相关的寄存器:
r0~r3:函数调用传入参数的前4个32位数据
r0:函数返回值
PSR寄存器(状态寄存器):
N:运算结果为负
Z:运算结果为零
C:运算发生进位
V:运算发生溢出
与后文cmp,s后缀和condition后缀相关
2. 常用指令
mov
mov r1, #5 ;r1 = 5
mov r1, r0 ;r1= r0
算术,逻辑指令
add r2, r0, r1 ;r2 = r0 + r1
ldr/str
ldr r1, [sp, #4] ;r1 = memory[sp + 4]
str r1, [sp, #4] ;memory[sp + 4] = r1
ldmxx/stmxx
该系列指令能够一次load/store多个寄存器,xx表示该系列指令的后缀,一般格式为:
[ldm|stm][d|i][b|a] 基址寄存器[!], {寄存器列表}
后缀所表达的意思
db: decrease before,表示从基址开始,对于列表中每个寄存器,地址减4而后load/store该寄存器值
da: decrease after,表示从基址开始,对于列表中每个寄存器,load/store该寄存器值而后地址减4
ib: increase before,表示从基址开始,对于列表中每个寄存器,地址加4而后load/store该寄存器值
ia: increase after, 表示从基址开始,对于列表中每个寄存器,load/store该寄存器值而后地址加4
!: 加上叹号表示同步改变基址寄存器的值
push/pop
操作sp的指令别名,其实就是stmdb sp!和ldmia sp!,主要在传递参数,保存/恢复寄存器上下文等情景下使用
push {r1, lr} ;相当于stmdb sp!, {r1, lr}
pop {r1, pc} ;相当于ldmia sp!, {r1, pc}
b/bl/bx/blx
b label ;跳转至label
bl lable ;跳转至label并链接,相当于先“mov lr, pc”再“b label”
bx r1 ;以r1的值为目标地址进行跳转
blx r1 ;以r1的值为目标地址进行跳转并链接,相当于先“mov lr, pc”再“bx r1”
cmp,s后缀和condition后缀
cmp指令和带S后缀的算术和逻辑指令会根据结果改变PSR的对应位,这样之后带有condition后缀的指令就可以根据情况来选择是否执行,例如:
int test(int a, int b) {
return a >= 0 ? a+b : a-b;
}
会被编译为:
cmp r0, #0 ;等价于subs r0, #0
addge r0, r0, r1
rsblt r0, r1, r0
bx lr
condition后缀包括eq(相等),ne(不等),lt(小于),gt(大于),le(小于等于),ge(大于等于)。
对于跳转指令来说,可以通过加入condition后缀来实现程序的分支和循环等控制逻辑。
注意Thumb状态下只有跳转指令可以带condition后缀。
总结
本文记录的指令只是ARM指令集中极小的一个子集,但已经能够满足大部分编程以及查看汇编代码的需求。
——寄存器、常用指令&spm=1001.2101.3001.5002&articleId=78251125&d=1&t=3&u=44e8185385b445fa86112e346e7c343d)
1726

被折叠的 条评论
为什么被折叠?



