ARM内核与寄存器

ARM内核与寄存器详解

目录

ARM架构概述

ARM(Advanced RISC Microprocessor)是一种RISC(精简指令集计算机)处理器架构,最初由Acorn计算机公司设计,现在由ARM公司开发和授权。由于其低功耗和高性能特性,ARM处理器广泛应用于移动设备、嵌入式系统和物联网设备。

ARM架构已经发展了多个版本,从ARMv1到最新的ARMv9,不同版本引入了不同的功能和改进。主要的架构系列包括:

  • Cortex-A系列:应用处理器,用于高性能系统
  • Cortex-R系列:实时处理器,用于需要快速响应的系统
  • Cortex-M系列:微控制器,用于低功耗嵌入式设备

ARM处理器模式

ARM处理器有多种操作模式,每种模式有不同的寄存器可见性和权限级别:

模式 描述 进入方式
用户模式 普通程序执行 程序正常运行
系统模式 特权操作系统任务 软件切换
管理模式 系统保护模式 软件中断
中止模式 处理内存访问违例 数据或指令预取中止
未定义模式 处理未定义指令 遇到未定义指令
快速中断模式 高优先级中断处理 FIQ中断
中断模式 中断处理 IRQ中断

Cortex-M3内核的处理器模式

注意:Cortex-M3内核采用了简化的处理器模式系统,与传统ARM架构不同。Cortex-M3主要有两种运行模式:

  1. 线程模式(Thread Mode) - 用于运行应用程序代码
  2. 处理器模式(Handler Mode) - 用于处理所有异常

Cortex-M3还引入了特权级别的概念:

  • 特权访问 - 可访问所有系统资源
  • 非特权访问 - 受限制的资源访问

以下是Cortex-M3中不同情况的模式对应关系:

传统ARM模式 Cortex-M3对应情况 实际例子
用户模式 线程模式(非特权) 运行普通应用程序代码,如循环计算任务
系统模式 线程模式(特权) 操作系统执行特权操作,如初始化外设、配置MPU
管理模式 通过SVC异常进入Handler模式 应用程序调用SVC指令请求操作系统服务,如SVC #0切换任务
中止模式 MemManage异常进入Handler模式 程序访问MPU禁止的内存区域;设置了只读区域但尝试写入
未定义模式 UsageFault异常进入Handler模式 执行了未支持的浮点指令;除零操作;未对齐的内存访问
快速中断模式 没有直接对应,所有中断进入Handler模式 EXTI外部中断;高优先级的ADC转换完成中断
中断模式 没有直接对应,所有中断进入Handler模式 UART接收完成中断;SysTick系统定时器中断
Cortex-M3异常处理示例:
  1. 硬故障(HardFault)例子:

    • 程序尝试执行未映射内存区域的代码
    • 访问了未对齐的内存地址
    • 在中断处理过程中出现嵌套错误
  2. SVC(管理模式)例子:

    c 复制代码
    // 通过SVC调用请求操作系统服务
    __asm("SVC #42");  // 调用42号系统服务,例如RTOS切换任务
  3. BusFault例子:

    c 复制代码
    // 访问无效的外设地址
    volatile uint32_t *ptr = (uint32_t *)0x60000000; // 假设这是无效总线地址
    *ptr = 0x1234;  // 触发BusFault异常
  4. 使用故障例子:

    c 复制代码
    // 未对齐的访问(如果启用了对齐检查)
    volatile uint32_t *ptr = (uint32_t *)0x20000001; // 非4字节对齐地址
    *ptr = 0x1234;  // 触发UsageFault异常

Cortex-A系列处理器模式

Cortex-A系列处理器保留了传统ARM架构的7种处理器模式,并增加了安全扩展和虚拟化扩展模式。以下是Cortex-A核在不同情况下的模式例子:

模式 Cortex-A对应情况 实际例子
用户模式 低特权应用程序 手机上运行的普通APP;Linux用户空间程序
系统模式 高特权操作系统代码 操作系统内核执行特权任务;驱动程序操作硬件
管理模式 系统调用处理 应用程序通过SWI/SVC请求系统服务;Android的Binder调用
中止模式 内存访问违例处理 程序访问受MMU保护的内存区域;Linux中的段错误(SIGSEGV)
未定义模式 处理未识别指令 程序执行平台不支持的指令;尝试执行NEON指令但硬件不支持
快速中断模式 高优先级外设中断 DMA传输完成;高速存储器控制器中断;显示刷新中断
中断模式 普通外设中断处理 触摸屏输入;按键中断;传感器数据就绪中断
监视模式 TrustZone安全世界 安全认证;指纹处理;支付系统隔离
虚拟机模式 虚拟化支持(ARMv7-A) 虚拟机管理程序;Docker容器环境切换
Cortex-A与Cortex-M主要区别:
  1. 处理器模式实现:

    • Cortex-A: 完整的7种模式+扩展模式,通过CPSR控制
    • Cortex-M: 简化为线程模式和处理器模式两种,通过异常入口管理
  2. 特权级别:

    • Cortex-A: 通过处理器模式区分特权
    • Cortex-M: 明确的特权/非特权状态区分
  3. 异常处理:

    • Cortex-A: 使用向量表+模式切换
    • Cortex-M: 统一的异常机制,自动保存/恢复上下文
Cortex-A异常处理示例:
c 复制代码
// Cortex-A中的异常向量表设置
// 通常在汇编启动文件中定义
void vectors(void) __attribute__((section("vectors")));
void vectors(void) {
    asm("b reset_handler");      // 复位处理
    asm("b undefined_handler");  // 未定义指令
    asm("b svc_handler");        // 软件中断(SVC)
    asm("b prefetch_handler");   // 取指中止
    asm("b data_handler");       // 数据中止
    asm("b unused_handler");     // 未使用
    asm("b irq_handler");        // 中断
    asm("b fiq_handler");        // 快速中断
}

// SVC示例 - Linux系统调用
int main() {
    int result;
    // 调用write系统调用(4号)
    asm("mov r0, #1");          // 文件描述符1(stdout)
    asm("ldr r1, =message");    // 消息缓冲区
    asm("mov r2, #13");         // 消息长度
    asm("mov r7, #4");          // write系统调用号
    asm("swi #0");              // 执行系统调用
    asm("mov %0, r0" : "=r" (result));
    return 0;
}

ARM寄存器集

通用寄存器

ARM架构提供16个32位通用寄存器(R0-R15),其中R13-R15有特殊用途:

寄存器 别名 描述 使用约定
R0 - 通用寄存器 第一个函数参数,函数返回值
R1-R3 - 通用寄存器 函数参数
R4-R11 - 通用寄存器 需在函数调用间保存
R12 IP 程序内部暂存寄存器 过程调用中临时使用
R13 SP 堆栈指针 指向当前堆栈顶部
R14 LR 链接寄存器 保存子程序返回地址
R15 PC 程序计数器 指向当前执行指令

程序计数器(PC)

PC寄存器(R15)保存当前执行指令的地址。在ARM状态下,PC指向当前指令地址+8;在Thumb状态下,PC指向当前指令地址+4。

使用方法:

  • 读取PC获得当前指令附近的地址
  • 向PC写入值实现跳转
assembly 复制代码
MOV R0, PC      @ 获取当前PC值
MOV PC, LR      @ 从子程序返回

链接寄存器(LR)

LR寄存器(R14)用于存储子程序返回地址。当执行BL(分支并链接)指令时,返回地址被自动保存到LR中。

使用方法:

  • 调用子程序前保存LR(如果子程序内还会调用其他函数)
  • 子程序返回时将LR的值复制到PC
assembly 复制代码
PUSH {LR}       @ 保存返回地址
BL subroutine   @ 调用子程序
POP {PC}        @ 恢复返回地址并返回

堆栈指针(SP)

SP寄存器(R13)指向当前堆栈顶部。ARM通常采用满递减(Full Descending)堆栈,即SP指向最后一个已入栈的数据项。

使用方法:

  • PUSH操作前先减少SP,再存储
  • POP操作先加载,再增加SP
assembly 复制代码
PUSH {R0-R3}    @ 将R0-R3压入堆栈
POP {R0-R3}     @ 从堆栈弹出到R0-R3

状态寄存器(CPSR/SPSR)

当前程序状态寄存器(CPSR)和保存的程序状态寄存器(SPSR)包含处理器状态信息。

CPSR字段:

  • 条件标志(N,Z,C,V):用于条件执行
  • 控制位:处理器模式、中断禁用标志、指令集状态等

条件标志:

  • N(负数):结果为负
  • Z(零):结果为零
  • C(进位):产生进位
  • V(溢出):有符号溢出
assembly 复制代码
CMP R0, R1      @ 比较R0和R1,设置条件标志
ADDPL R0, R0, #1 @ 如果结果非负(N=0)则执行加法

协处理器寄存器

ARM架构支持协处理器扩展,包括CP15系统控制协处理器。CP15寄存器控制缓存、MMU、系统控制和配置。

访问方法:

assembly 复制代码
MRC p15, 0, R0, c1, c0, 0  @ 读取CP15 c1寄存器到R0
MCR p15, 0, R0, c1, c0, 0  @ 写入R0到CP15 c1寄存器

NEON和VFP寄存器

现代ARM架构包含NEON和VFP(向量浮点)扩展,提供额外的寄存器用于SIMD和浮点运算:

  • 32个64位寄存器(D0-D31)
  • 也可视为16个128位寄存器(Q0-Q15)
assembly 复制代码
VMOV.F32 S0, #1.0        @ 加载浮点常量到S0
VADD.F32 S0, S0, S1      @ 浮点加法
VLDM R0, {D0-D3}         @ 加载多个64位寄存器

寄存器使用规范

ARM架构定义了AAPCS(ARM架构过程调用标准)规范:

  • R0-R3:参数传递和结果返回,调用者保存
  • R4-R11:局部变量,被调用者保存
  • R12(IP):内部过程调用暂存,调用者保存
  • R13(SP):堆栈指针,被调用者保存
  • R14(LR):链接寄存器,被调用者保存
  • R15(PC):程序计数器

参数传递机制

当函数参数超过4个时,ARM采用以下策略:

  • 前4个参数通过R0-R3寄存器传递
  • 额外的参数通过栈传递,从右到左入栈
  • 参数在栈上按照4字节对齐
  • 被调用者负责从栈上获取额外参数

示例:调用有6个参数的函数func(a, b, c, d, e, f)

assembly 复制代码
MOV R0, #1          @ 第一个参数 a
MOV R1, #2          @ 第二个参数 b
MOV R2, #3          @ 第三个参数 c
MOV R3, #4          @ 第四个参数 d
PUSH {R5, R6}       @ 将第五和第六个参数入栈 (f先入栈,e后入栈)
MOV R5, #6          @ 第六个参数 f (先入栈)
MOV R6, #5          @ 第五个参数 e (后入栈)
PUSH {R5, R6}
BL func             @ 调用函数
ADD SP, SP, #8      @ 调用完成后恢复栈(清理参数)

对于返回值:

  • 32位或更小的返回值保存在R0中
  • 64位返回值使用R0和R1
  • 更大的结构体通过引用返回,调用者提供内存地址作为隐式第一个参数

常见ARM指令与寄存器操作

数据处理指令:

assembly 复制代码
MOV R0, R1          @ R0 = R1
ADD R0, R1, R2      @ R0 = R1 + R2
SUB R0, R1, #1      @ R0 = R1 - 1
AND R0, R1, #0xFF   @ R0 = R1 & 0xFF

内存访问指令:

assembly 复制代码
LDR R0, [R1]        @ 从R1指向的地址加载到R0
STR R0, [R1, #4]    @ 存储R0到R1+4指向的地址
LDMIA R1!, {R0-R4}  @ 多寄存器加载,递增后更新R1
STMDB R13!, {R0-R3} @ 多寄存器存储,递减前更新R13

分支指令:

assembly 复制代码
B label             @ 无条件分支
BL function         @ 分支并链接(调用子程序)
BX LR               @ 分支并切换状态(常用于返回)
CMP R0, #0          @ 比较R0与0
BEQ zero_label      @ 相等时分支

条件执行:

assembly 复制代码
ADDEQ R0, R0, R1    @ 当Z=1时执行加法
MOVNE R0, #0        @ 当Z=0时执行赋值
相关推荐
HQB202610 小时前
EG1198|屹晶微电子 120V 内置 MOS 异步降压 DC‑DC(高性价比)
嵌入式硬件·硬件工程
果壳science11 小时前
张祥前实验如何获取正电荷
笔记·科技·嵌入式硬件·硬件工程·制造
南山电子nscn11 小时前
中科芯CETC汽车电池管理系统BMS进口芯片国产型号替代指南
单片机·汽车·bms
沉淀的.晴天12 小时前
can总线
stm32
桀人12 小时前
认识AT24C02
stm32·单片机·嵌入式硬件
大叔学Linux13 小时前
FreeRTOS任务切换笔记
arm开发·笔记
国科安芯13 小时前
星间激光通信终端CANFD控制网络的时延确定性与辐射可靠性
网络·嵌入式硬件·信息与通信·canfd·低轨卫星·商业航天·抗辐射
一直C14 小时前
嵌入式 Linux 驱动开发学习笔记:内核定时器、platform 总线与 I²C 驱动
linux·驱动开发·嵌入式硬件·学习·imx6ull
传感器与混合集成电路14 小时前
150MHz主频、8路DAC与6路PWM:JLH221360伺服控制SIP解析
嵌入式硬件
comyccccc14 小时前
STM32PID控制板设计全解析学习笔记
单片机·嵌入式硬件