ARM内核与寄存器

ARM内核与寄存器详解

目录

  • ARM架构概述
  • ARM处理器模式
    • Cortex-M3内核的处理器模式
    • Cortex-A系列处理器模式
  • ARM寄存器集
    • 通用寄存器
    • 程序计数器(PC)
    • 链接寄存器(LR)
    • 堆栈指针(SP)
    • 状态寄存器(CPSR/SPSR)
  • 协处理器寄存器
  • NEON和VFP寄存器
  • 寄存器使用规范
  • 常见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(管理模式)例子

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

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

    // 未对齐的访问(如果启用了对齐检查)
    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异常处理示例:
// 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-通用寄存器需在函数调用间保存
R12IP程序内部暂存寄存器过程调用中临时使用
R13SP堆栈指针指向当前堆栈顶部
R14LR链接寄存器保存子程序返回地址
R15PC程序计数器指向当前执行指令

程序计数器(PC)

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

使用方法:

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

链接寄存器(LR)

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

使用方法:

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

堆栈指针(SP)

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

使用方法:

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

状态寄存器(CPSR/SPSR)

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

CPSR字段:

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

条件标志:

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

协处理器寄存器

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

访问方法:

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)
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)

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指令与寄存器操作

数据处理指令:

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

内存访问指令:

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

分支指令:

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

条件执行:

ADDEQ R0, R0, R1    @ 当Z=1时执行加法
MOVNE R0, #0        @ 当Z=0时执行赋值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/75318.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git 拉取时常见冲突及解决方法总结

Git 拉取时常见冲突及解决方法总结 一、常见错误场景1. 本地修改与远程修改冲突解决方法 2. 未跟踪文件与远程文件冲突解决方法 3. 子模块权限问题解决方法 二、总结 在日常开发中,使用 Git 进行团队协作和代码管理时,经常会遇到拉取代码(git…

深度学习、图像算法学习记录

深度学习加速 综述文档: https://chenzomi12.github.io/02Hardware01Foundation/02ArchSlim.html winograd: https://zhuanlan.zhihu.com/p/260109670 ncnn 1.修改模型结构,优化模型内存访问次数,加速。 VGG 和 InceptionNet : …

Java中的Exception和Error有什么区别?还有更多扩展

概念 在Java中,Exception和Error都是Throwable的子类,用于处理程序中的错误和异常情况。 然而,它们在用途和处理方式上有显著的不同: Exception: 用于表示程序在正常运行过程中可能出现的错误,如文件未找…

文章记单词 | 第26篇(六级)

一,单词释义 actor:名词,演员mask:名词,面具;口罩;遮盖物;动词,掩饰;戴面具;遮盖construct:动词,建造;构造&a…

LeetCode算法题(Go语言实现)_38

题目 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 一、代码实现 type TreeNode struct {Val intLeft *TreeNodeRight *TreeNode }func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {if root nil || root p || root q {return root}left : lowes…

Java 基础语法、Java注释

Java 基础语法 一个 Java 程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。下面简要介绍下类、对象、方法和实例变量的概念。 对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫…

用VScode来编写前后端——构建基础框架

前言 我写这一个板块的原因是我参加了我们学校的新生项目课,需要创立一个系统,我们小组选的标题的基于计算机视觉的商品识别系统,那么我们需要一个网站来展示我们的功能,故写这些来记录一下自己,大家如果有什么问题的话…

git clone阻塞问题

问题描述 git clone采用的ssh协议,在克隆仓库的时候,会经常卡一下,亦或是直接卡死不动。 最开始以为是公司电脑配置的问题,想着自己实在解决不了找it帮忙。 查阅资料发现,最终发现是git版本的问题,这个是…

WEB攻防-Java安全JNDIRMILDAP五大不安全组件RCE执行不出网不回显

目录 1. RCE执行-5大类函数调用 1.1 Runtime方式 1.2 Groovy执行命令 1.3 脚本引擎代码注入 1.4 ProcessImpl 1.5 ProcessBuilder 2. JNDI注入(RCE)-RMI&LDAP&高版本 2.1 RMI服务中的JNDI注入场景 2.2 LDAP服务中的JNDI注入场景 攻击路径示例&#…

【Hadoop入门】Hadoop生态之Sqoop简介

1 什么是Sqoop? 在企业的数据架构中,关系型数据库与Hadoop生态系统之间的数据流动是常见且关键的需求。Apache Sqoop(SQL-to-Hadoop)正是为解决这一问题而生的高效工具,它专门用于在结构化数据存储(如RDBMS…

如何自动检测使用的组件库有更新

🤖 作者简介:水煮白菜王,一位前端劝退师 👻 👀 文章专栏: 前端专栏 ,记录一下平时在博客写作中,总结出的一些开发技巧和知识归纳总结✍。 感谢支持💕💕&#…

Go语言编写一个进销存Web软件的demo

Go语言编写一个进销存Web软件的demo 用户现在要求用。之前他们已经讨论了用Django实现的方案,现在突然切换到Go,可能有几个原因。首先,用户可能对Go语言感兴趣,或者他们公司的技术栈转向了Go。其次,用户可能希望比较不…

【前缀和】矩阵区域和(medium)

矩阵区域和(medium) 题⽬描述:解法:代码Java 算法代码:C 算法代码: 题⽬描述: 题⽬链接:1314. 矩阵区域和 给你⼀个 m x n 的矩阵 mat 和⼀个整数 k ,请你返回⼀个矩阵 …

Java学习手册:Java发展历史与版本特性

Java作为全球最流行的编程语言之一,其发展历程不仅见证了技术的演进,也反映了软件开发模式的变革。从1995年的首次发布到如今的持续更新,Java始终保持着强大的生命力和广泛的影响力。本文将简要回顾Java的发展历程,并重点介绍其关…

winserver2022备份

安装备份,然后等待安装完成即可 然后可以在这里看到安装好的win server2022备份 一直下一步然后到这里 不要用本地文件夹备份 备份到远程服务器,远程服务器路径 然后确定备份即可 如何恢复呢? 点击右侧的恢复就可以了 打开任务计划程序 这…

Unity 设置弹窗Tips位置

根据鼠标位于屏幕的区域&#xff0c;设置弹窗锚点以及位置 public static void TipsPos(Transform tf) {//获取ui相机var uiCamera GetUICamera();var popup tf.GetComponent<RectTransform>();//获取鼠标位置Vector2 mousePos Input.mousePosition;float screenWidt…

【C++基础-关键字】:extern

深入理解 C++ 关键字 extern 在 C++ 编程中,extern 关键字扮演着重要角色,主要用于声明全局变量或函数,使其在多个源文件间共享。本文将详细探讨 extern 的用法及其在实际开发中的应用。 1. 什么是 extern? extern 关键字用于声明一个变量或函数的引用,表示该变量或函数…

我为女儿开发了一个游戏网站

大家好&#xff0c;我是星河。 自从协助妻子为女儿开发了算数射击游戏后&#xff0c;星河就一直有个想法&#xff1a;为女儿打造一个专属的学习游戏网站。之前的射击游戏虽然有趣&#xff0c;但缺乏难度分级&#xff0c;无法根据女儿的学习进度灵活调整。而且&#xff0c;仅仅…

基于 Python 卷积神经网络的新闻文本分类系统,附源码

大家好&#xff0c;我是徐师兄&#xff0c;一个有着7年大厂经验的程序员&#xff0c;也是一名热衷于分享干货的技术爱好者。平时我在 CSDN、掘金、华为云、阿里云和 InfoQ 等平台分享我的心得体会。今天我来跟大家聊聊一个用 Python 和 Django 打造的人脸识别考勤系统&#xff…

ngx_cycle_modules

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_cycle_modules-CSDN博客 定义在 src/core/ngx_module.c ngx_int_t ngx_cycle_modules(ngx_cycle_t *cycle) {/** create a list of modules to be used for this cycle,* copy static modules to it*/cycle->modules ngx_pcalloc(…