嵌入式学习day46-硬件—汇编

1. 保护现场(压栈)

保护现场的核心思想是 将寄存器的内容保存到栈中,确保在执行函数调用或处理中断时,能够保存当前的上下文(如寄存器值),等到处理完后恢复。

常见步骤:

  1. 将重要寄存器压入栈中:

    • 通常会保存 R0-R12 (通用寄存器),以及 LR (链接寄存器)和 CPSR(当前程序状态寄存器)。

    • 通过 STMFD(Store Multiple Full Descending)指令将多个寄存器压入栈中。

  2. 保存现场:

    • 执行 STMFDPUSH 指令,将寄存器的值保存到栈中。

    示例:保护现场并保存寄存器:

    复制代码

    asm

    STMFD SP!, {R0-R12, LR} ; 将 R0-R12 和 LR 保存到栈中,SP 自减

    解释:

    • STMFD 表示 Store Multiple Full Descending,将多个寄存器存储到栈中。

    • SP! 表示栈指针 自减,即将栈向低地址方向增长。

    • {R0-R12, LR} 表示保存寄存器 R0 到 R12,以及链接寄存器 LR。

  3. 注意:

    • ARM 中的栈是全递减栈(Full Descending Stack),即每次操作栈时,栈指针会先自减,然后存取数据。栈向低地址方向增长。

2. 恢复现场(弹栈)

恢复现场是将压入栈中的寄存器值恢复回寄存器中,从而保证程序在保护和恢复后能继续执行原来的操作。恢复现场的步骤通常会在函数执行完毕或者中断处理完后执行。

常见步骤:

  1. 将寄存器从栈中弹出:

    • 使用 LDMFD(Load Multiple Full Descending)指令从栈中恢复多个寄存器的值。
  2. 恢复现场:

    • 执行 LDMFDPOP 指令,将栈中的值恢复到相应的寄存器。

    示例:恢复现场并恢复寄存器:

    复制代码

    asm

    LDMFD SP!, {R0-R12, LR} ; 从栈中恢复 R0-R12 和 LR 的值

    解释:

    • LDMFD 表示 Load Multiple Full Descending,从栈中加载多个寄存器的值。

    • SP! 表示栈指针自增,即恢复栈指针。

    • {R0-R12, LR} 表示恢复寄存器 R0 到 R12 和 LR 的值。

  3. 注意:

    • ARM 中的 弹栈操作压栈操作 一致,也是全递减栈。

  • LDR 用于从内存加载数据到寄存器。

  • STR 用于将寄存器的值存储到内存中。


1. ARM 汇编调用 C 语言函数及 C 语言调用汇编函数的参数和返回值处理

在 ARM 汇编和 C 语言混合编程中,函数调用是通过标准的调用约定(calling convention)进行的。ARM 体系结构的标准调用约定是 ARM EABI(Embedded Application Binary Interface),它定义了函数参数、返回值以及寄存器的使用规则。

ARM 汇编调用 C 语言函数
  1. 函数参数传递:

    • ARM 汇编中的函数调用遵循 ARM EABI 约定,函数参数通过寄存器传递。前四个参数使用寄存器 r0r3 传递,如果有更多参数,则通过栈传递。

    • 示例:

      • r0 传递第一个参数

      • r1 传递第二个参数

      • r2 传递第三个参数

      • r3 传递第四个参数

      • 之后的参数通过栈传递。

  2. 返回值:

    • C 语言函数的返回值通常存储在寄存器 r0 中。函数执行完后,返回值通过 r0 返回给调用者。
  3. 调用过程:

汇编中通过 bl (Branch with Link) 指令调用 C 语言函数。bl 会将当前地址保存到 lr(Link Register)中,返回时会从 lr 中恢复。

示例:假设调用一个 C 语言函数 c_add,则汇编代码会像这样

复制代码
ldr r0, =a   ; 加载参数 a
ldr r1, =b   ; 加载参数 b
bl c_add     ; 调用 C 语言函数

返回时,C 函数的返回值会存放在 r0 中,汇编可以通过 r0 读取返回值。

C 语言调用汇编函数
  1. 函数参数传递:

    • C 语言中的函数调用会将参数传递给汇编函数,C 函数遵循 ARM EABI 约定,前四个参数也通过寄存器 r0r3 传递。

    • 示例:C 函数中传递参数给汇编函数 asm_func

      复制代码
      asm_func(a, b);

      汇编中的 asm_func 定义如下:

      复制代码
      asm_func:
          mov r0, r0   ; 将传递的第一个参数保存到 r0
          mov r1, r1   ; 将传递的第二个参数保存到 r1
          ...
          bx lr        ; 返回

      asm_func: mov r0, r0 ; 将传递的第一个参数保存到 r0 mov r1, r1 ; 将传递的第二个参数保存到 r1 ... bx lr ; 返回

  2. 返回值:

    • 汇编函数的返回值也通过 r0 寄存器传递给 C 语言函数。

    • C 函数会根据汇编函数的返回值做相应处理。

  3. 调用过程:

    • C 语言使用标准函数调用方式,传递参数并接收返回值。ARM 汇编函数使用 bx lr 指令返回,lr(Link Register)存储了调用时的返回地址。

2. ARM 内核中的异常及其工作模式

ARM 内核支持多种类型的异常(exception),这些异常使得处理器切换到不同的工作模式,以处理硬件或软件中断。

ARM 内核中的几种异常:
  1. Reset Exception(复位异常):

    • 当处理器上电或复位时,会触发复位异常,处理器进入 Reset 模式

    • 该异常是处理器启动时的第一个异常,用于初始化系统。

  2. Undefined Instruction Exception(未定义指令异常):

    • 当处理器遇到一个未定义的指令时,会触发此异常。

    • 处理器进入 Undefined 模式

  3. Software Interrupt Exception(软件中断异常,SWI):

    • 由软件发出的 swi 指令触发,通常用于系统调用或用户请求服务。

    • 处理器进入 Supervisor 模式

  4. Prefetch Abort Exception(预取中止异常):

    • 当处理器尝试访问一个无效的指令地址时,触发预取中止异常。

    • 处理器进入 Abort 模式

  5. Data Abort Exception(数据中止异常):

    • 当处理器尝试访问一个无效的数据地址时,触发数据中止异常。

    • 处理器进入 Abort 模式

  6. IRQ (Interrupt Request) Exception(外部中断请求异常):

    • 当外部硬件或外部设备触发中断时,处理器响应此异常。

    • 处理器进入 IRQ 模式

  7. FIQ (Fast Interrupt Request) Exception(快速中断请求异常):

    • 与 IRQ 异常类似,但它是为高优先级中断设计的,处理速度较快。

    • 处理器进入 FIQ 模式

  8. SWI (Software Interrupt) Exception(软件中断异常):

    • 当执行 swi 指令时,触发此异常。它通常用于系统调用或程序控制流。

    • 处理器进入 Supervisor 模式

ARM 异常导致的工作模式切换:

ARM 处理器在遇到不同类型的异常时,会根据异常的种类切换到不同的工作模式(Mode)。这些模式如下:

  1. User Mode(用户模式):

    • 用户程序执行时的默认模式。具有最小的权限,不能访问受保护的资源。
  2. FIQ Mode(快速中断模式):

    • 用于处理快速中断(FIQ),具有高优先级和快速响应能力。
  3. IRQ Mode(普通中断模式):

    • 用于处理外部中断(IRQ),优先级低于 FIQ,但高于 User Mode。
  4. Supervisor Mode(管理模式):

    • 用于处理软件中断(SWI)等操作,具有更高的权限。
  5. Abort Mode(中止模式):

    • 用于处理数据或指令访问错误,处理器会在此模式下处理访问异常。
  6. Undefined Mode(未定义模式):

    • 当遇到未定义指令时切换到此模式,用于处理无法识别的指令。
  7. System Mode(系统模式):

    • 处理器处于操作系统级别的模式,通常用于管理系统资源,权限最高。
相关推荐
西岸行者7 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
我在人间贩卖青春7 天前
汇编之伪指令
汇编·伪指令
悠哉悠哉愿意8 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码8 天前
嵌入式学习路线
学习
毛小茛8 天前
计算机系统概论——校验码
学习
babe小鑫8 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms8 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下8 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。8 天前
2026.2.25监控学习
学习
im_AMBER8 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode