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 个参数通过栈传递。
相关推荐
程序员-Benothing2 小时前
Linux文件查看与编辑:cat、less、tail、vim快速入门
linux·运维·服务器
国科安芯3 小时前
卫星电源管理系统中宽温域低功耗MCU的选型与适应性分析
嵌入式硬件·mcu·抗干扰·抗辐射·宽温
AlanBruce9 小时前
摩尔信使MThings功能综述与应用使用指南
linux·自动化·plc·mthings·摩尔信使
老当益壮梁奶奶11 小时前
51单片机DS18B20温度传感器详解:单总线时序与C51驱动实现
笔记·stm32·单片机·嵌入式硬件·51单片机
Horn Still Sounds11 小时前
ARM嵌入式基础|内核、寄存器、架构、存储、汇编移位全面梳理
arm开发·单片机·嵌入式硬件·硬件架构
susplus11 小时前
【初识ARM】ARM相关基础概念
学习·arm
星栖与芯11 小时前
LiteOS-M 切换汇编逐行图解(2):指令·异常机制·全景表
stm32·单片机·嵌入式硬件·harmonyos·鸿蒙系统
myy-learn13 小时前
ARM-知识扫盲1
arm
从零开始的嵌入式之旅13 小时前
day44
arm开发·经验分享·笔记·嵌入式硬件