Linux入门DAY44 ARM 入门 Day02|ARM 汇编指令、模式切换、栈操作、汇编 C 混合编程

#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。

  1. MRS:特殊寄存器 → 通用寄存器(读)
  2. 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 置 1
  • bic:按位清除,把指定 bit 置 0

三、内存读写指令 LDR / STR

ARM 内核不能直接对内存 RAM 读写,必须借助寄存器中转。

  1. LDR:把内存 (RAM/NOR Flash) 的数据加载到通用寄存器

    ldr r0, [r1] ;将r1指向内存的数据读到r0

注意区分:ldr内存加载指令 和 ldr伪指令(加载立即数)。

  1. 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

  1. STMFD:满减栈入栈,寄存器压栈保存现场

    stmfd sp!, {r0,r1,lr} ;把r0、r1、lr压入栈,!表示更新sp

  2. 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 知识点小结

  1. ADD 算术指令,S 后缀影响状态位;ARM 立即数有编码限制,不是所有数字都能 #直接使用。
  2. MRS 读 CPSR/SPSR,MSR 写 CPSR/SPSR,用于切换处理器工作模式;orr 置 1,bic 清 0。
  3. LDR 读内存到寄存器,STR 写寄存器到内存,ARM 不能直接操作内存。
  4. B 跳转无返回;BL 函数调用保存 LR;BX lr 完成函数返回。
  5. ARM 默认满减栈 ,stmfd入栈保护现场,ldmfd出栈恢复现场。
  6. 汇编、C 互相调用:前 4 个参数 R0‑R3 传递,返回值 R0;多于 4 个参数通过栈传递。
相关推荐
黑妹天下第一乖11 小时前
第 11 讲:阿加犀 AidLux 多组件综合实战——端侧“智能摄像头解说“全链路
人工智能·嵌入式硬件·语言模型·自然语言处理·iot
py有趣11 小时前
硬件SPI和软件模拟SPI在配置方面的一点区别
c语言·stm32·单片机
lisanmengmeng11 小时前
NRPE 添加命令(三)
java·linux·服务器
AUTO_1507567596511 小时前
【KT70022】昆腾微 单片音频编解码器
单片机·音频
人工智能培训11 小时前
数字孪生驱动大模型工业知识库:为具身机器人植入领域专业经验
大数据·linux·服务器·前端·人工智能
江屿风12 小时前
【Linux系统】【从菜鸟驿站到操作系统:一节课打通Linux重定向与缓冲区真相】流食般投喂
linux·运维·服务器·开发语言·笔记
LCG元12 小时前
STM32F103 GPIO 翻转方式耗时实测:CRL/CRH 逐位拆解、BSRR 原子写与 ODR 读改写竞态陷阱
stm32·单片机·嵌入式硬件
今天要早睡_12 小时前
Linux 基础指令速查:从 ls 到 tar 的常用命令全解析
linux·运维·chrome
搁浅小泽12 小时前
压敏电阻(MOV)选型与设计规范
单片机·嵌入式硬件
高山有多高12 小时前
【Linux笔记】UDP协议
linux