学习arm汇编时知识点整理

发布于 2022-08-31 01:55:21

arm是有别与X86的cpu架构,这里整理学习arm汇编时收集的知识点

查看更多

浏览量
6222
猫哥
猫哥 项目组成员 2022-08-31
希望我的回答能对你有所帮助
10 个回答
猫哥
猫哥 项目组成员 2022-08-31
希望我的回答能对你有所帮助

ARM寄存器

共拥有 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位寄存器

猫哥
猫哥 项目组成员 2022-08-31
希望我的回答能对你有所帮助

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常用指令:

image.png

猫哥
猫哥 项目组成员 2022-08-31
希望我的回答能对你有所帮助

ARM使用加载(Load)/存储(Stroe)指令来读写内存,这意味着你只能使用LDR和STR指令访问内存。在ARM上数据必须从内存中加载到寄存器之后才能进行其他操作,而在x86上大部分指令都可以直接访问内存中的数据。

猫哥
猫哥 项目组成员 2022-09-05
希望我的回答能对你有所帮助

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时跳转

猫哥
猫哥 项目组成员 2022-08-31
希望我的回答能对你有所帮助

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

猫哥
猫哥 项目组成员 2022-08-31
希望我的回答能对你有所帮助

小端模式 litte-endian 低位字节存储在低位地址,高位字节存储在高位地址。
大端模式 bug-endian 刚好相反

数据访问的是小端还是大端,由程序状态寄存器CPSR 的第9位E标志控制

猫哥
猫哥 项目组成员 2022-08-31
希望我的回答能对你有所帮助
分支跳转指令

B - 无条件跳转
BX - 带链接跳转
BLX - 带状态切换的跳转

猫哥
猫哥 项目组成员 2022-09-05
希望我的回答能对你有所帮助

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),用于指向每个函数的栈顶。

猫哥
猫哥 项目组成员 2022-09-05
希望我的回答能对你有所帮助

armv8 arm64 表示arm公司支持64位指令集的处理器架构,广泛用于移动数字产品中。
aarch64 是 armv8的编程模型

学习
记录

发布
问题

分享
好友

手机
浏览

扫码手机浏览