共拥有 30 个 32位寄存器。前16个可在用户模式下访问,又分为两组,通用寄存器和特殊用途寄存器。
对应于x86寄存器的关系;
r0 = ax
r1~r5 = bx, cx, dx, si, di
r6~r10
r11 = BP
r12
r13 = sp 栈指针
r14 链接寄存器,保存函数返回后需要继续执行的指令。
r15 = ip arm模式下始终为4个字节,也就是两个arm指令。
cpsr = flag
-N 负数标志位
-Z 0值标志位
-C 进位标志位
-V 溢出标志位 超过2^31或小于-2^31,就会溢出。
有 32 个主寄存器 x0–x30(64 位版本)或 w0–w30(32 位版本)。x31 是用作堆栈指针的特殊情况寄存器。
w0 32为寄存器
x0 64位寄存器
arm指令格式:(由于ARM指令集的灵活性,并不是所有的指令都用到这些字段。这些字段的解释如下)
MNEMONIC{S}{condition} {Rd}, Operand1, Operand2
-------
MNEMONIC - 操作指令(机器码对应的助记符)。
{S} - 可选后缀. 如果指定了该后缀,那么条件标志将根据操作结果进行更新。
{condition} - 执行指令所需满足的条件。
{Rd} - 目标寄存器,存储操作结果。
Operand1 - 第一操作数(寄存器或者立即数)
Operand2 - 第二操作数. 立即数或者带有位移操作后缀(可选)的寄存器。
MNEMONIC, S, Rd和Operand1字段比较明了,condition 和 Operand2字段需要再解释一下。condition字段与CPSR寄存器的值有关,准确的说是和CPSR某些位有关。Operand2也叫可变操作数,因为它可以有多种形式--立即数、寄存器、带有位移操作的寄存器。例如Operand2可以有以下多种形式:
#123 - 立即数。
Rx - 寄存器x (如 R1, R2, R3 ...)。
Rx, ASR n - 寄存器x,算术右移n位 (1 = n = 32)。
Rx, LSL n - 寄存器x,逻辑左移n位 (0 = n = 31)。
Rx, LSR n - 寄存器x,逻辑右移n位 (1 = n = 32)。
Rx, ROR n - 寄存器x,循环右移n位 (1 = n = 31)。
Rx, RRX - 寄存器x,扩展的循环位移,右移1位。
ARM使用加载(Load)/存储(Stroe)指令来读写内存,这意味着你只能使用LDR和STR指令访问内存。在ARM上数据必须从内存中加载到寄存器之后才能进行其他操作,而在x86上大部分指令都可以直接访问内存中的数据。
RET 指令 函数执行完成,需要继续执行进入函数前(BL 跳转前)的下一条指令执行的话,要将下一条指令的地址,保存在 LR 寄存器(X30)中。
RET 指令会默认使用 LR 寄存器(X30)中的值,通过底层指令提示 CPU 此处作为下条指令地址。
在 ARM64 中,我们可以使用 BL 指令来修改 PC 寄存器的值,使程序跳转到指定内存处执行。
SP 寄存器在任意时刻都保存栈顶的地址。也就是说 SP 寄存器指向哪里,哪里就是栈。
FP 寄存器也称为 x29 寄存器,属于通用寄存器,在某些时刻我们利用它保存栈底的地址。
str r0,[r1,#0x10] 把r0寄存器的值,放入r1的内存地址中
stur r0,[r1,#-0x10] 与上面的区别是,立即数是负数, u表示负数。
stp w0,w1,[x2] p是pair一对的意思,表示把一对寄存器push到栈中
adrp x9,0x22 将pc的值后三位清零 与 0x22左移三位后的值 相加。 作用是找出获取参数的地址范围,然后将pc寄存器执行的代码定位到准确的屋里地址上。通过基地址 + 偏移 获得一个字符串(全局变量)
movk x8,#0xD,LSL#32 将 16 位立即移入寄存器,保持其他位不变。这行指令是指左移32位后存入寄存器x8
b 无条件跳转
cb 有条件跳转
cbz 结果为0时跳转
cbnz 结构不为0时跳转
ld = load 加载内存数据,st = store 存储内存数据
-s = signed 有符号数
-h -sh 半字型(16位2个字节)
-b -sb 字节型(8位1个字节)
-r word 字型(32位4个字节)
ldr = load word
ldrh = load unsigned half word
ldrsh = load signed half word
ldrb = load unsigned byte
ldrsb = load signed byte
str = store word
strh = store unsigned half word
strsh = store signed half word
strb
strsb
LDP x29,x30,[sp,#0x40+0]
LDP x20,x19,[sp,#0x40+10]
ADD sp,sp,#0x50
RET
这段代码的解释是 return X 返回一个结果数值
x19~x28:临时寄存器,子程序使用时必须保存。
x0~x7:传递子程序的参数和返回值,使用时不需要保存,多余的参数用堆栈传递,64位的返回结果保存在x0中。
x8:用于保存子程序的返回地址,使用时不需要保存。
x9~x15:临时寄存器,也叫可变寄存器,子程序使用时不需要保存。
x16~x17:子程序内部调用寄存器(IPx),使用时不需要保存,尽量不要使用。
x18:平台寄存器,它的使用与平台相关,尽量不要使用。
x19~x28:临时寄存器,子程序使用时必须保存。
x29:帧指针寄存器(FP),用于连接栈帧,使用时必须保存。
x30:链接寄存器(LR),用于保存子程序的返回地址。
x31:堆栈指针寄存器(SP),用于指向每个函数的栈顶。