ARM汇编
寻址方式
ARM汇编转换网站:https://armconverter.com/
寄存器间接寻址
LDR指令
将内存中的数据加载到寄存器中
ARM32: LDR R1, [R2] --> R1 = *R2 |
STR指令
将寄存器的数据存入内存中
ARM32: STR R1, [R2] --> *R2 = R1 |
基址变址寻址
ARM32: LDR R1, [R2, #4] --> R1 = *(R2+4); |
LDR R4, [R10, R2, LSL #1] -->R4 = *(R10 + R2<<1) |
ARM32栈寻址
入栈 STMFD SP!, {R0-R3} 从右往左 --> PUSH{R!!, LR} |
ARM64栈寻址
STP X29, X30, [SP, #0x10] |
ARM32读写PC寄存器
ARM32可以直接读写PC
ARM32:写PC寄存器 写多少就是多少
MOV PC, #0x6000
写PC寄存器相当于无条件跳转
ARM32:读PC寄存器,ARM指令+8, Thumb指令+4
ADD PC, PC, #4c
跳转指令相当于间接读写PC寄存器
ARM64读写PC寄存器
ARM64不能直接读写PC寄存器,只能间接读写PC寄存器
ADR、ADRP、ADRL相当于间接读PC
一般定位全局资源会用到,字符串、全局变量等
跳转指令相当于间接读写PC寄存器
ARM64读PC,就是当前指令的地址,不需要额外加值
MOV指令
指令里的立即数不是随便放的,常规情况下可以携带16个bit位
ARM64
movz w8, #0x5678 会将其他bit位清零 |
ARM32
MOV R0, #0x5678 |
读内存,地址需要四字节对齐,如果不齐就需要向下取整
主要出现在ARM32中,ARM64除了数据以外基本都是4字节的,很少有这个问题
比如,[0x14c6]相当于读[0x14c4]
指令后缀
同一指令附带不同后缀,具有额外作用
常用后缀
B(byte)功能不变,操作长度变成8位,LDRB
H(half word) 功能不变,长度变为16位,LDRH
S(signed)功能不变,操作数变为有符号,LDRSB
S(S标志)功能不变,影响CPSR标志位,MOVS
SPSR标志位
N:结果为负数时N=1,结果为正数或零时N=0
Z:结果为0时Z=1,否则Z=0
C:一般情况下加法进位,减法无借位时C=1,对于结合以为操作的非加/减法指令,C为最后移出的值
V:当进行加法/减法运算,并且有符号溢出时V=1,否则V=0,其它指令V通常不变
条件执行后缀
ARM32
CMP R0, R1 |
ARM64
B.NE loc_1730 |
调用约定
参数的传递
ARM32:前四几个寄存器R0-R3存参数,更多的存栈中
ARM64:前八个寄存器X0-X7存参数,更多的存栈中
结果的传递
ARM32:R0,不够就加上R1
ARM64:X0,返回结构体有可能存放在X8里面