#ARM #嵌入式 #Cortex‑A7 #ARM汇编 #裸机开发
前言
接着上一篇 ARM Day01 基础,本篇学习 ARM 汇编核心指令、处理器模式切换、立即数、内存读写、跳转指令、栈操作以及汇编与 C 语言混合编程,是裸机汇编开发必掌握内容。
环境:Cortex‑A7,ARMv7 32 位汇编
一、算术加法 ADD 指令
指令格式
ADD{S}<c> <Rd>, <Rn>, #<const> ;立即数加法
ADD{S}<c> <Rd>, <Rn>, <Rm> ;寄存器相加
ADD{S}<c> <Rd>, <Rn>, <Rm>, <type> <Rs> ;寄存器+移位后寄存器
-
S:带 S 后缀会影响 CPSR 状态标志位,不加 S 不改变标志位 -
示例:
add r0, r1, #3 ; r0 = r1 + 3
add r0, r1, r2 ; r0 = r1 + r2
add r0, r1, r2, lsl r3 ; r0 = r1 + (r2 << r3)
ARM 立即数
立即数不是任意 32 位数,硬件编码限制:由8 位基础数 + 循环右移偶数位组合而成。
不是所有常数都可以当作立即数,不能编码的数值,不能直接用
#立即数,要用 LDR 伪指令加载。
二、特殊寄存器读写 MRS / MSR
CPSR、SPSR 属于特殊状态寄存器,不能直接用 mov 读写,必须使用 MRS、MSR。
- MRS:特殊寄存器 → 通用寄存器(读)
- MSR:通用寄存器 → 特殊寄存器(写)
示例:切换 CPU 到 USER 用户模式
mrs r0, cpsr ;把cpsr读取到r0
bic r0, r0, #0x1F ;清除模式位
orr r0, r0, #0x10 ;设置模式位为USER(10000)
msr cpsr, r0 ;写回cpsr,完成模式切换
模式位低 5bit 决定处理器工作模式。
orr:按位或,用来把指定 bit 置 1bic:按位清除,把指定 bit 置 0
三、内存读写指令 LDR / STR
ARM 内核不能直接对内存 RAM 读写,必须借助寄存器中转。
-
LDR:把内存 (RAM/NOR Flash) 的数据加载到通用寄存器
ldr r0, [r1] ;将r1指向内存的数据读到r0
注意区分:
ldr内存加载指令 和ldr伪指令(加载立即数)。
-
STR:把通用寄存器的值写入内存 RAM
str r0, [r1] ;将r0的值存储到r1指向的内存地址
C 语言逻辑翻译成汇编举例
示例 1:求 1~100 累加
int i = 0;
int sum = 0;
for(i = 1; i <= 100; i++){
sum += i;
}
会使用:寄存器保存 i、sum,比较指令做循环判断,add 做累加,ldr/str 访问内存变量。
示例 2:三数求最大值
int a=3,b=5,c=7,max;
max = a;
if(b>max) max = b;
if(c>max) max = c;
汇编通过 cmp 比较 + 条件执行指令实现 if 判断。
四、跳转指令 B / BL / BX
表格
| 指令 | 作用 |
|---|---|
| B | 无条件跳转,不保存返回地址,常用于循环 |
| BL | 跳转并且把返回地址保存到 LR (R14),用于函数调用 |
| BX | 跳转,可以切换 ARM/Thumb 状态;bx lr实现函数返回,等价mov pc,lr |
示例:
b loop ;跳转到loop标签,循环
bl func ;调用func函数,返回地址存lr
bx lr ;函数返回
五、ARM 栈模型 & 栈操作指令
栈四种类型
- 增栈:入栈 SP 向高地址增长
- 减栈:入栈 SP 向低地址增长
- 满栈:先移动 SP 指针,再存数据
- 空栈:先存数据,再移动 SP 指针
ARM 默认使用:满减栈(STMFD / LDMFD)
栈操作指令 STMFD / LDMFD
-
STMFD:满减栈入栈,寄存器压栈保存现场
stmfd sp!, {r0,r1,lr} ;把r0、r1、lr压入栈,!表示更新sp
-
LDMFD:满减栈出栈,恢复寄存器现场
ldmfd sp!, {r0,r1,lr} ;从栈恢复r0、r1、lr,sp自动恢复
函数进入用 STMFD 保护寄存器,函数返回前 LDMFD 恢复现场。
六、汇编与 C 语言混合编程
1)汇编调用 C 函数
-
参数 ≤4 个:用 R0~R3 依次传递参数
-
参数>4 个:多余参数压入栈传递
-
C 函数返回结果:返回值放到 R0 寄存器给汇编使用
bl c_func ;跳转到C语言函数,参数提前放到r0‑r3
2)C 语言调用汇编函数
-
C 传入的前 4 个参数自动放到 R0~R3
-
汇编函数运算完成,把返回结果存入 R0,C 语言接收返回值
extern int asm_add(int a,int b); //声明外部汇编函数
调用约定重点:R0‑R3 传参,R0 存返回值,超过 4 个参数走栈。
Day02 知识点小结
- ADD 算术指令,S 后缀影响状态位;ARM 立即数有编码限制,不是所有数字都能 #直接使用。
- MRS 读 CPSR/SPSR,MSR 写 CPSR/SPSR,用于切换处理器工作模式;orr 置 1,bic 清 0。
- LDR 读内存到寄存器,STR 写寄存器到内存,ARM 不能直接操作内存。
- B 跳转无返回;BL 函数调用保存 LR;BX lr 完成函数返回。
- ARM 默认满减栈 ,
stmfd入栈保护现场,ldmfd出栈恢复现场。 - 汇编、C 互相调用:前 4 个参数 R0‑R3 传递,返回值 R0;多于 4 个参数通过栈传递。