ARM汇编笔记(1)——寄存器、常用指令

来源:互联网 发布:婚庆四件套 知乎 编辑:程序博客网 时间:2024/05/20 02:54

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, #0addge  r0, r0, r1rsblt  r0, r1, r0bx     lr

condition后缀包括eq(相等),ne(不等),lt(小于),gt(大于),le(小于等于),ge(大于等于)。
对于跳转指令来说,可以通过加入condition后缀来实现程序的分支和循环等控制逻辑。
注意Thumb状态下只有跳转指令可以带condition后缀。

总结
本文记录的指令只是ARM指令集中极小的一个子集,但已经能够满足大部分编程以及查看汇编代码的需求。

原创粉丝点击