说明:整理汇编学习笔记,包含算数指令、MRS/MSR、内存读写、跳转、栈操作、汇编 C 混合调用。
一、ADD 加法指令格式
ADD 是加法指令,{S}代表是否影响 CPSR 状态寄存器,<c>代表条件执行。 三种常用语法格式:
;格式1:寄存器 + 立即数
ADD{S}<c> <Rd>, <Rn>, #<const>
add r0, r1, #3 ; r0 = r1 + 3
;格式2:寄存器 + 寄存器
ADD{S}<c> <Rd>, <Rn>, <Rm>
add r0, r1, r2 ; r0 = r1 + r2
;格式3:寄存器 + 移位后的寄存器
ADD{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
add r0, r1, r2, lsl r3 ; r0 = r1 + (r2 逻辑左移r3位)
小知识点:ARM 汇编的立即数有特殊限制,支持 8/10/11/12 位编码,不是随便一个数字都能当立即数。
二、MRS / MSR 特殊寄存器读写
普通汇编指令不能直接操作 CPSR/SPSR 这类特殊寄存器,必须用 MRS、MSR 两条指令中转。
MRS:把特殊寄存器的值读到通用寄存器MSR:把通用寄存器写回特殊寄存器
示例:切换到 USER 用户模式的操作步骤
-
使用
mrs把 cpsr 读取到 r0 -
修改 r0 里面对应的模式位
-
使用
msr把修改完的 r0 写回 cpsrmrs r0, cpsr ;读取CPSR到R0
; 修改r0的模式位
msr cpsr, r0 ;把修改后的值写回CPSR
三、内存加载与存储指令 LDR / STR
ARM 架构不能直接对内存运算,数据要先读到寄存器,运算完再写回内存。
- LDR:把 RAM 中的数据加载到通用寄存器;也可以用来加载不能作为立即数的常量。
- STR:把通用寄存器的数据,写入到 RAM 内存。
内存地址示例 RAM (4KB):
0x40000000 ~ 0x40001000Nor Flash(2MB):0x200000 ~ 0x1FFFFF
四、位操作 ORR 指令
orr或指令,用来把寄存器的某些 bit 置 1,对应位输入为 1 则输出结果 bit 置 1。
五、跳转指令 b /bl/bx
-
b 无条件跳转 单纯跳转,不会保存返回地址,常用于循环、长跳转。
b 循环标签
b 函数标签 -
bl 带返回地址跳转(函数调用) 跳转之前,自动把下一条指令地址存入 LR (R14) 链接寄存器,用于函数返回。
-
bx 跳转,支持切换指令集
bx lr等价于mov pc, lr,最常用做函数返回。
六、ARM 栈模型 & 栈操作指令
ARM 栈分为 4 种类型:满减栈、满增栈、空增栈、空减栈
- 增栈:入栈的时候 sp 向高地址移动
- 减栈:入栈的时候 sp 向低地址移动
- 满栈:先移动 sp 指针,再写入数据
- 空栈:先写入数据,再移动 sp 指针
ARM 默认使用满减栈
两条栈操作指令:
-
STMFD:入栈,把多个寄存器压入栈,!表示更新 sp 指针stmfd sp!, <r0,r1,lr> ;保存r0 r1 lr到栈上
-
LDMFD:出栈,从栈恢复寄存器数据ldmfd sp!, <r0, r1, lr> ;从栈恢复r0 r1 lr
七、汇编与 C 语言混合编程
1、汇编调用 C 函数
- 参数≤4 个:使用 R0‑R3 寄存器传递参数
- 参数>4 个:多余参数放到栈上面传递
- C 函数计算得到的返回值,统一放到 R0 返回给汇编。
2、C 语言调用汇编函数
- C 传给汇编的前 4 个参数存放在 R0‑R3 寄存器
- 汇编函数计算结束,结果放到 R0,返回给 C 语言。
八、简单 C 逻辑翻译成汇编的思路
写汇编的时候就是把 C 逻辑翻译成寄存器操作。
示例 1:1~100 求和
int i = 0;
int sum = 0;
for (i = 1; i <= 100; i++) {
sum += i;
}
示例 2:三数求最大值
int a = 3; int b = 5; int c = 7; int max;
max = a;
if(b>max){ max = b; }
if (c > max) { max = c; }
写汇编思路:变量放到寄存器,比较跳转实现 if、for 循环逻辑。
📝Day02 小结
这一天主要熟悉 ARM 汇编基础指令。重点记住:特殊寄存器要用 MRS/MSR 访问;CPU 运算只能在寄存器完成,读写内存靠 LDR/STR;函数调用靠 bl,返回靠 bx lr;栈操作 STMFD/LDMFD;C 和汇编交互依靠 R0~R3 传参,R0 带回返回值。