ARM的异常处理机制

article/2025/9/14 0:14:59

异常种类

ARM共有如下7种异常模式:

  • 复位(RESET):当处理器复位引脚有效时,系统产生复位异常中断。复位异常中断通常在系统加电和系统复位时发生,直接跳转到复位中断向量处执行称为软复位。
  • 未定义的指令(UDEF):当ARM处理器或者是系统中的协处理器认为当前指令未定义时,会产生未定义的指令异常中断。
  • 软件中断(SWI):这是一个由SWI指令触发的中断。
  • 指令预取终止(PrefechAbort):如果处理器预取的指令的地址不存在,或者该地址不允许当前指令访问,就会产生指令预取终止异常中断。
  • 数据访问终止(DATAABORT):如果数据访问指令的目标地址不存在,或者该地址不允许当前指令访问就会产生数据访问终止异常中断。
  • 外部中断请求(IRQ):当处理器的外部中断请求引脚有效,而且CPSR的寄存器的I控制位被清除时,就会产生外部中断请求异常中断。
  • 快速中断请求(FIQ):当处理器的外部快速中断请求引脚有效,并且CPSR的F控制位被清除时,就会产生外部中断请求异常中断。

异常中断向量表

        当异常发生时,CPU会主动将PC赋值为低地址或高地址,该地址处有一条指令用于处理该类型异常,我们将存储这些指令的地方称为异常中断向量表。ARM规定每个向量占用4字节空间(通常会放一个跳转指令或一个向PC寄存器赋值的数据访问指令。通过这两种指令,将程序跳转到相应的异常中断处理程序处执行),共32个字节。

        异常发生时,ARM会将处理其切换到对应的模式来处理异常。此外,不同种类的异常有可能会同时发生,此时ARM会按照一定的优先级策略来处理这些异常。

        上述相关的信息见下表所示。

 

        图中未定义指令与软件中断异常的优先级都是6,这其实没有关系,因为这两类异常不可能同时发生。 

异常处理

        要实际处理上述七种异常,需要软硬件的协同,这里记录的是硬件对异常的处理步骤,并不涉及软件部分。在实际编程过程中,只有首先明白硬件对异常处理逻辑后,才能正确的进行软件处理。

        硬件对异常的处理分为两部分:发生异常时的处理(进入部分)和异常结束处理(离开部分),而且无论是哪种异常,硬件对它们的处理过程大致相同,只有个别的细节不同,下面首先讨论共性,然后再具体类型具体说明。

进入部分

        当异常发生时,处理器大致按照如下的流程进行处理:

  1. 将下一条指令的地址保存在对应模式的LR寄存器中,异常处理退出时需要;
  2. 保存处理器当前状态,即将CPSR保存到相应的模式的SPSR中;
  3. 修改CPSR中的相应位,包括设置模式位和中断屏蔽位;
  4. 将PC设置成对应的异常中断向量的地址。

        上述过程用伪代码表示为:

R14_<exception_mode> = return link
SPSR_<exception_mode> = CPSR
CPSR[4:0] = exception mode number
CPSR[5] = 0 //异常处理时处理器一定是工作在ARM状态的
if <exception_mode> == Reset or FIQ thenCPSR[6] = 1 //有条件的屏蔽FIQ中断
CPSR[7] = 1 // 总是屏蔽IRQ中断
PC = exception vector address

复位异常

R14_svc = UNPREDICTABLE value
SPSR_svc = UNPREDICTABLE value
CPSR[4:0] = 0b10011 // 复位异常在特权模式下运行
CPSR[5] = 0
CPSR[6] = 1 // 关闭FIR和IRQ中断
CPSR[7] = 1
if high vectors configured thenPC = 0xFFFF0000
elsePC = 0x00000000

        注意:复位异常的处理是不需要返回的,所以其R14和SPSR的值是未定义的。

未定义指令异常

R14_und = PC - 4
SPSR_und = CPSR
CPSR[4:0] = 0b11011 // 处理器进入未定义指令模式
CPSR[5] = 0
CPSR[7] = 1 // 只禁止IRQ,FIQ不变
if high vectors configured thenPC = 0xFFFF0004
elsePC = 0x00000004

SWI软件中断

R14_svc = PC - 4
SPSR_svc = CPSR
CPSR[4:0] = 0b10011 // 处理器进入特权模式
CPSR[5] = 0
CPSR[7] = 1 // 只禁止IRQ,FIQ不变
if high vectors configured thenPC = 0xFFFF0008
elsePC = 0x00000008

指令预取中止异常中断

R14_abt = PC - 4
SPSR_abt = CPSR
CPSR[4:0] = 0b10111 // 处理器进入中止模式
CPSR[5] = 0
CPSR[7] = 1 // 只禁止IRQ,FIQ不变
if high vectors configured thenPC = 0xFFFF000C
elsePC = 0x0000000C

数据访问中止异常中断

R14_abt = PC - 4
SPSR_abt = CPSR
CPSR[4:0] = 0b10111 // 处理器进入中止模式
CPSR[5] = 0
CPSR[7] = 1 // 只禁止IRQ,FIQ不变
if high vectors configured thenPC = 0xFFFF0010
elsePC = 0x00000010

IRQ异常

R14_irq = PC - 4
SPSR_irq = CPSR
CPSR[4:0] = 0b10010 // 处理器进入IRQ模式
CPSR[5] = 0
CPSR[7] = 1 // 只禁止IRQ,FIQ不变
if high vectors configured thenPC = 0xFFFF0018
elsePC = 0x00000018

FIQ异常

R14_fiq = PC - 4
SPSR_fiq = CPSR
CPSR[4:0] = 0b10001 // 处理器进入FIQ模式
CPSR[5] = 0
CPSR[6] = 1 // 禁止FIQ、IRQ
CPSR[7] = 1
if high vectors configured thenPC = 0xFFFF0018
elsePC = 0x00000018

离开部分

        当异常处理结束后,需要执行如下两步操作才能返回到被异常中断的地方继续执行:

  1. 恢复处理器状态,即把SPSR_mode的内容复制到CPSR中;
  2. 清除相应的中断禁用标记;
  3. 根据lr_mode的值恢复PC的值,从而从被中断的地方继续执行。

SWI软件中断

未定义指令异常中断

        由于这两种异常是在指令执行过程中发生的,此时PC指向当前指令后面的第二条指令(对于ARM状态为当前指令地址加8,对于THUMB状态为当前指令地址加4),因为在中断发生时,处理器将PC-4的结果保存到了lr_mode中,所以在返回时,只需要直接将lr_mode的值复制到PC中即可。

IRQ和FIR异常中断

        因为对IRQ和FIQ的处理是在一条指令结束时发生的,此时PC的值指向当前指令后面的第三条指令(对于ARM状态为当前指令地址加12,对于THUMB状态为当前指令地址加6),因为在中断发生时,处理器将PC-4的结果保存到了lr_mode中,所以在返回时,需要将lr_mode-4的结果赋值给PC。

指令预取中止异常

        指令预取中止异常虽然在指令的取址阶段就发生了,但是真正对该异常的处理是在执行该指令时发生的,此时PC的值指向当前指令后面的第二条指令(对于ARM状态为当前指令地址加8,对于THUMB状态为当前指令地址加4)。该异常的处理结束返回时,应该返回到产生该异常的指令地址处重新执行该指令,而不是返回到产生该异常的指令的下一条指令处执行。因为在中断发生时,处理器将PC-4的结果保存到了lr_mode中,所以在返回时,需要将lr_mode-4的结果赋值给PC。

数据访问中止异常

        发生该异常时,PC指向当前指令后面的第三条指令(对于ARM状态为当前指令地址加12,对于THUMB状态为当前指令地址加6)。同样的,对该异常的处理返回时,应该返回到产生该异常的指令地址处重新执行该指令。因为在中断发生时,处理器将PC-4的结果保存到了lr_mode中,所以在返回时,需要将lr_mode-8的结果赋值给PC。


http://chatgpt.dhexx.cn/article/LHxNU060.shtml

相关文章

spring异常处理

在项目中采用spring的异常处理机制&#xff1a; 示例一、在Controller中加ExceptionHandler注解定义异常拦截的方法&#xff0c;在方法中定义返回的页面&#xff1a; Controller public class ExceptionTestController {ExceptionHandlerpublic String handleException(Excep…

C语言异常处理

文章目录 前言一、 异常表达二、 异常报告三、 异常处理 前言 错误与异常&#xff1a; 错误与异常都是在程序编译或者运行时出现的错误&#xff0c; 不同的是&#xff0c;异常可以被开发人员捕捉和处理&#xff1b;而错误&#xff0c;一般不需要开发人员处理&#xff08;也无法…

SpringBoot全局异常处理

文章目录 异常处理方案分类基于请求转发基于异常处理器基于过滤器 常见异常处理实现方案1. BasicExceptionController2. ExceptionHandler3. ControllerAdviceExceptionHandler4. SimpleMappingExceptionResolver5. HandlerExceptionResolver6. Filter 全局异常处理实现方案1. …

springboot整合之统一异常处理

特别说明&#xff1a;本次项目整合基于idea进行的&#xff0c;如果使用Eclipse可能操作会略有不同&#xff0c;不过总的来说不影响。 springboot整合之如何选择版本及项目搭建 springboot整合之版本号统一管理 springboot整合mybatis-plusdurid数据库连接池 springboot整合…

C++ 异常处理

目录 一、异常的定义 二、异常的抛出和捕获 1.throw 2.try...catch 3.异常安全 4.异常规范 三、系统预定义异常 四、用户自定义异常 一、异常的定义 异常在C用于错误处理&#xff0c;C语言中一般使用返回值表示错误&#xff0c;C对错误处理进行了扩展&#xff0c;统一使…

关于异常处理的知识整理

目录 1.什么是异常&#xff1f; 2.异常继承结构 3.异常结构继承图 4.关于异常处理的两种方式&#xff1a; 5.异常对象有两个非常重要的方法 1.什么是异常&#xff1f; 程序在执行过程中不正常的情况称为异常&#xff0c;以类和对象的形势存在&#xff0c;可以通过异常类&am…

异常处理---

异常 异常处理 例&#xff1a; public class Demo{public static void main(String[] args) {System.out.println("开始");method();System.out.println("结束");}public static void method(){int[] arr{1,2,3};System.out.println(arr[3]);//数组索引…

异常处理

1.相关概念的介绍 1&#xff09;异常情形&#xff1a;是指阻止当前方法或作用域继续执行的问题。 2&#xff09;监控区域&#xff1a;一段可能产生异常的代码&#xff0c;并且后面跟着处理这些异常的代码。 3&#xff09;try块&#xff1a;如果在方法的内部或者在方法内部调…

异常及异常处理

一、异常的概念 定义&#xff1a; 异常指的是运行期出现的错误&#xff0c;也就是当程序开始执行以后执行期出现的错误。 处理态度&#xff1a; 当捕获到异常以后一定要做出处理&#xff0c;哪怕是把这个异常的错误信息打印出来&#xff0c;这是一种良好的编程习惯。 …

异常处理(throw、throws、try-catch)

Java异常处理的五个关键字try、catch、finally、throw、throws 1.抛出异常throw 在编写程序时&#xff0c;我们必须要考虑程序出现问题的情况。比如&#xff0c;在定义方法时&#xff0c;方法需要接收参数。那么&#xff0c;当调用方法使用接收到的参数时&#xff0c;首先需要…

SpringBoot+Axis2搭建WebService服务端

SpringBootAxis2搭建WebService服务端 之前用过Spring Axis2搭建过WebService项目&#xff0c;网上也有很多资料教程&#xff0c;最近需要在一个SpringBoot项目中添加Axis2的服务端&#xff0c;在网上找了很久&#xff0c;没有找到相关教程&#xff0c;最终经过大神朋友的指点…

AXI(2)完结

四、握手 4.1握手过程 所有的五个通道都是通过相同的VALID/READY握手处理来传输地址、数据和控制信息。 双向握手的机制意味着主机和从机之间传输数据时&#xff0c;都可以控制传输的速率&#xff0c;只有当VALID和READY同时为高电平时&#xff0c;传输才会发生。 发送方&a…

读Axis2用户帮助文档 (axis2中文文档)

作者&#xff1a;李红霞 时间&#xff1a;2006-10-19 声明&#xff1a;本文可以算作Axis2用户手册的翻译&#xff0c;但是翻译后的文本是经过作者理解写出来的&#xff0c;可能有些偏差&#xff0c;欢迎讨论。本文属作者原创&#xff0c;允许转载&#xff0c;但请注明出处。 英…

AXI 3.0 (1)

一、AXI简介 AMBA3.0中新增加了一种总线——AXI&#xff08;Advanced eXtensible Interface&#xff0c;高级扩展接口&#xff09;。 AMBA AXI 协议的目标是高性能、高频的系统设计&#xff0c;其包含了若干特性。 适合高带宽和低延迟的设计 提供高频操作&#xff0c;无需使…

Apache axis2 + Eclipse 开发 WebService

一、简介 Apache Axis2是下一代 Apache Axis。Axis2 虽然由 Axis 1.x 处理程序模型提供支持&#xff0c;但它具有更强的灵活性并可扩展到新的体系结构。Axis2 基于新的体系结构进行了全新编写&#xff0c;而且没有采用 Axis 1.x 的常用代码。支持开发 Axis2 的动力是探寻模块化…

Axis2与Web项目整合

一、说明: 上一篇介绍了通过使用Axis2来发布和调用WebService&#xff0c;但是是把WebService发布在Axis2提供的项目中&#xff0c;如果我们需要在自己的Web项目中来使用Axis2发布WebService该怎么做呢&#xff1f; 本篇即介绍在Web项目中使用Axis2来发布WebService. 二、具体…

Axis2中文手册

中文原文 http://tenn.javaeye.com/blog/100736 英文原文 http://ws.apache.org/axis2/1_0/userguide.html 概述 这个说明文档涉及以下内容&#xff1a;  如何使用 axis2 创建 web service 和客户端程序  如何定制一个模块 (Module) 并在 web service 中使用它  Sam…

axis2的使用(转载)

通过axis2发起WS请求时添加SOAP header 首先要获得一个ServiceClient对象&#xff0c;因为这个对象是org.apache.axis2.client.Stub里面定义的&#xff0c;所以你生成的stub里面应该直接就可以使用这个对象&#xff0c;或者调用stub的_getServiceClient()方法来获取这个对象。 …

SpringBoot2 整合 AXIS2 服务端和客户端

文章目录 一、AXIS2服务端1. 版本选型2.导入依赖3. services.xml4.Axis2配置类5.服务接口6.服务接口实现类7. FileCopyUtils工具类8. 测试验证 二、AXIS2服务端2.1. 客户端类2.2. 服务调用测试开源源码. 一、AXIS2服务端 1. 版本选型 阿健/框架版本spring-boot2.5.5axis21.7.…

WebService之Axis2系列教程(一)Axis2的下载、安装和使用

Axis2是目前比较流行的WebService引擎。WebService被应用在很多不同的场景。例如&#xff0c;可以使用WebService来发布服务端 Java类的方法&#xff0c;以便使用不同的客户端进行调用。这样可以有效地集成多种不同的技术来完成应用系统。WebService还经常被使用在SOA中&#x…