当前位置: 首页 > news >正文

ARM 处理器异常处理机制详解

目录

异常

异常源

异常处理

异常向量表

安装设置异常向量表及保存现场指令

异常处理的返回

异常源与异常模式对应关系

异常响应优先级


ARM7-11 有7种基本工作模式,而 Cortex-A 系列处理器则额外支持 Monitor 模式:

  • User:非特权模式,大部分任务执行在这种模式。
  • FIQ:当一个高优先级(fast)中断产生时将会进入这种模式。
  • IRQ:当一个低优先级(normal)中断产生时将会进入这种模式。
  • Supervisor/SVC:当复位或软中断指令执行时将会进入这种模式。
  • Abort:当存取异常时将会进入这种模式。
  • Undef:当执行未定义指令时会进入这种模式。
  • System:使用和 User 模式相同寄存器集的特权模式。
  • Monitor:Cortex-A 特有模式,用于执行安全监控代码的模式;也是一种特权模式。

异常

异常是处理器处理特定事件的方式,中断是异常的一种形式。处理器遇到异常后会暂停当前的程序转而去处理异常(执行异常处理程序),处理完成后返回到被异常打断的代码处继续执行。

异常源

导致异常产生的事件有7个:

  1. Reset 复位异常:当 CPU 刚上电或按下 reset 重启键之后进入该异常,该异常在 SVC 模式下处理。
  2. IRQ/FIQ 一般/快速中断请求:CPU 和外部设备是分别独立的硬件执行单元,CPU 要想知道外部设备的运行状态,需要通过中断请求,根据请求的紧急情况分为一般中断和快速中断。
  3. PrefetchAbort 预取指令中止异常:该异常发生在 CPU 流水线取指阶段,如果目标指令地址是非法地址进入该异常,该异常在 Abort 模式下处理。
  4. Undef 未定义指令异常:该异常发生在流水线技术里的译码阶段,如果当前指令不能被识别为有效指令,产生未定义指令异常,该异常在 Undef 模式下处理。
  5. SWI 软件中断指令异常:该异常是应用程序自己调用时产生的,用于用户程序申请访问硬件资源时,例如:printf() 打印函数,该异常在 SVC 模式下处理。
  6. DataAbort 数据中止访问异常:该异常发生在要访问数据地址不存在或者为非法地址时,该异常在 Abort 模式下处理。
异常处理

异常处理的步骤(自动完成):

  1. 保存执行状态:将当前的 CPSR 保存到 SPSR_<mode> 中。
  2. 模式切换:进入 ARM 状态,并进入相应的异常模式,同时禁止相应中断。
  3. 保存返回地址:跳转到异常处理之前,将 PC 下一条指令地址保存到 LR_<mode> 中。
  4. 设置 PC 为相应的异常向量地址:修改 PC 切换到异常处理位置。
异常向量表

异常向量表是处于内存中的一段空间,为每个异常源分配了四个字节的存储空间。当产生了异常后 PC 的值会自动变成该异常源在异常向量表中的地址。我们可以在这段地址写一条跳转指令使其跳转到异常处理程序入口。

安装设置异常向量表及保存现场指令
  1. 安装异常向量表:我们可以通过简单的使用下面的指令来安装异常向量表:
    b reset   ; 跳入 reset 处理程序
    b undef_handler ; 跳入未定义处理程序
    b swi_handler    ; 跳入软中断处理程序
    b pref_handler  ; 跳入预取指令处理程序
    b data_handler   ; 跳入数据访问中止处理程序
    b res ; 跳入未使用程序
    b irq_handler   ; 跳入中断处理程序
    b fiq_handler  ; 跳入快速中断处理程序
  2. 保存执行现场:异常处理程序最开始,要保存被打断程序的执行现场,可以通过下面的栈操作指令实现保存现场:
    stmfd sp!, {r0-r1, lr}

    需要注意的是,在跳转到异常处理程序入口时,已经切换到对应异常模式下了,因此这里的SP是异常模式下的SP了,所以被打断程序现场(寄存器数据)是保存在异常模式下的栈里,上述指令将R0~R1全部都保存到了异常模式栈,最后将修改完的被打断程序返回地址入栈保存,之所以保存该返回地址就是将来可以通过类似:MOV PC, LR的指令,返回用户程序继续执行。

    异常发生后,要针对异常类型进行处理,因此,每种异常都有自己的异常处理程序,中断异常处理过程通过系统中断处理来进行分析。

异常处理的返回

异常处理完成之后,返回被打断程序继续执行,具体操作如下:

  1. 恢复被打断程序运行时寄存器数据(从栈中恢复)。
  2. 恢复程序运行时状态 CPSR(恢复 SPSR_<mode> 到 CPSR)。
  3. 通过进入异常时保存的返回地址,返回到被打断程序继续执行(恢复 LR_<mode> 到 PC)。
异常源与异常模式对应关系
  • 异常源:FIQ、IRQ、Reset/软中断、DataAbort/PrefetchAbort、Undef。
  • 异常模式:FIQ、IRQ、SVC、Abort、Undef。
异常响应优先级
  • 优先级:Reset、Data Abort、FIQ、IRQ、Prefetch Abort、SWI、Undefined instruction。
  • 从高到低

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • MYSQL----表的创建
  • 海量数据的处理方法
  • 【C语言初阶】C语言指针全攻略:解锁C语言深层奥秘的钥匙
  • Springboot集成Mybatis在不同文件夹下出现同名文件时启动报错
  • Java实现pdf/word文字识别,调用OCR提取图片文字聚合
  • 厦门商家微信小程序、抖音、支付宝小程序同步上线
  • C语言宏中“#”和“##”的用法
  • 优先级队列的实现
  • 【uniapp】vue3+vite配置tailwindcss
  • 力扣热题100_链表_234_回文链表
  • ubuntu设置共享文件夹,非虚拟机,服务器版
  • XSS DOM漏洞复现 与DOM 破坏
  • ARM/Linux嵌入式面经(二四):国光电器
  • 雷达气象学(9)——反射率因子图分析(强对流篇)
  • 二十、观察者模式
  • 【笔记】你不知道的JS读书笔记——Promise
  • Apache Spark Streaming 使用实例
  • JS函数式编程 数组部分风格 ES6版
  • Spring-boot 启动时碰到的错误
  • vue2.0开发聊天程序(四) 完整体验一次Vue开发(下)
  • windows下mongoDB的环境配置
  • 大快搜索数据爬虫技术实例安装教学篇
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 深度解析利用ES6进行Promise封装总结
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 想使用 MongoDB ,你应该了解这8个方面!
  • 由插件封装引出的一丢丢思考
  • ​用户画像从0到100的构建思路
  • #FPGA(基础知识)
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (BAT向)Java岗常问高频面试汇总:MyBatis 微服务 Spring 分布式 MySQL等(1)
  • (ISPRS,2023)深度语义-视觉对齐用于zero-shot遥感图像场景分类
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (代码示例)使用setTimeout来延迟加载JS脚本文件
  • (四)进入MySQL 【事务】
  • (万字长文)Spring的核心知识尽揽其中
  • (转)程序员技术练级攻略
  • (转)创业的注意事项
  • .helper勒索病毒的最新威胁:如何恢复您的数据?
  • .NET Core 版本不支持的问题
  • .NET MAUI Sqlite数据库操作(二)异步初始化方法
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • .php文件都打不开,打不开php文件怎么办
  • .project文件
  • //TODO 注释的作用
  • @RequestMapping 和 @GetMapping等子注解的区别及其用法
  • [ vulhub漏洞复现篇 ] Grafana任意文件读取漏洞CVE-2021-43798
  • [2669]2-2 Time类的定义
  • [ACM独立出版] 2024年虚拟现实、图像和信号处理国际学术会议(VRISP 2024,8月2日-4)
  • [Android] 240204批量生成联系人,短信,通话记录的APK
  • [BZOJ3757] 苹果树
  • [CakePHP] 在Controller中使用Helper