《Cortex?-A系列编程者指南(V3.0)》第12章<异常处理>笔记

  在本章,我们看看ARM处理器如何响应异常。异常是任何需要挂起正常执行转而运行与每个异常类型相关联软件(称为异常处理程序)的条件。

12.1 异常的类型

  如我们在第四章看到,A系列和R系列架构支持七种处理器模式,六种特权模式(称为快速中断模式外部中断模式管理模式中止模式未定义模式系统模式),一种非特权模式(用户模式)。如果虚拟化扩展和安全扩展被实现,Hyp和Monitor模式可以被添加到列表。当前模式在软件控制下处理一个异常时修改。

  然而,非特权的用户模式只能通过产生一个异常来切换到另一个模式

  当一个异常发生,处理器保存当前状态和返回地址,进入一个指定的模式,并且可能会禁止硬件中断。执行从一个称为异常向量的固定的内存地址恢复。这自动地发生,不在编程者的直接控制之下。

  有下列异常类型存在:

<中断>

  ARMv7-A处理器上有两种类型的中断,称为IRQ和FIQ。FIQ比IRQ优先级高。FIQ有些潜在地速度优势,归因于它在向量表中的位置和在FIQ模式中可获取到更高数目的分组寄存器。这潜在地节省处理器在处理句柄中压入寄存器到堆栈的时钟周期。这类异常都典型地与处理器上的输入引脚相关联
--- 假设中断没有被禁止,外部硬件发出一个中断请求,在当前指令完成执行时,相应的异常类型被引发。

<中止>

  中止可以从指令获取失败(预取中止)数据访问失败(数据中止)中产生。它们可以来自外部存储器系统在存储器访问时给予一个错误响应(表示可能指定的地址与系统中实际内存不对应)。或者,中止可能会由处理器的内存管理单元(MMU)产生。操作系统可以使用MMU中止来动态分配内存给应用

  一个指令当它被获取时,可以在流水线中被标记为中止。预取中止异常在处理器确实尝试去执行它时。异常在指令实际执行前产生。如果流水线在中止指令到达流水线执行阶段之前被清空,中止异常不会发生。数据中止异常在加载或存储指令执行时发生,被认为在数据读或写已经尝试之后发生。

  如果中止作为指令流执行或尝试执行后的结果,它被描述为同步的返回地址会提供引起异常指令的细节。异步中止不是由正在执行指令产生的,同时返回地址可能不总是提供引起中止的细节。

  ARMv7架构区分精确与不精确的异步中止。由MMU产生的中止总是同步的。架构不需要外部中止访问的特定类型是同步的。

  例如,在一个特定的处理器实现上,它可能是这样的,报道了一个页表的步行外部中止被视为精确的,但对于所有的处理器,这不是必须的。对于精确的异步中止,中止处理程序可以确定哪个指令引起了中止,没有后续指令在那个指令之后被执行。这与不精确的异步中止作对比,它是外部存储器系统在一个无法识别的访问上报告一个错误时的结果。

  在这种情况下,中止处理函数不能确定那个指令引起了这个问题(引起中止产生的指令之后的指令可能已经执行)。例如,如果一个缓冲的写从外部存储器系统接收到一个错误响应,后续指令会在存储之后已被执行。这意味着对于中止处理函数,修复问题并返回给应用程序是不可能的。所有它能做的就是杀死引起这个问题的应用。因此设备检测需要特殊的处理,因为在读取不到的区域中,外部报告的中止会产生不精确的同步中止,甚至在这样的内存被标记为强排序的或设备。

  异步中止的检测由CPSR的A位控制。如果A位置位,来自外部存储器系统的异步中止会被处理器识别,中止异常不会立即产生。反而,处理器保持中止挂起直到A位被清除并在那时获取一个异常。典型地内核代码会确保(通过使用一个屏障指令)挂起的异步中止会确认正确的应用程序。如果一个线程由于一个不精确的中止已被杀死,它需要是正确的一个。

<复位>

  所有的处理器都有一个复位输入,并且会在它们被复位后立即产生复位异常。这是最高优先级的异常,不能被屏蔽

<异常指令>

  在ARM处理器上,有两类指令会引起异常。第一种是超级用户调用(Supervisor
Call ,SVC)
,以前被称为软件中断(Software Interrupt,SWI)典型地,这被用于提供一种机制,用户模式程序可以传递控制到特权的操作系统中的内核代码,来执行操作系统级任务。第二种是未定义指令。架构定义了特定位模式与未定义操作码对应。尝试其中之一会引起一个未定义指令异常的产生。另外,对于没有相应协处理器硬件执行的协处理器指令,也会引起这一陷阱产生。一些指令只能在特权模式被执行,在用户模式执行这些指令会引起未定义指令异常。

  当一个异常发生时,代码执行传递到一个被称为向量表的内存区域在表内,每一种异常类型只分配了一个字,通常包含一个到实际异常处理函数的分支指令。这个行为与大多数其它的架构不同,其它的架构通常在异常表中存储一个执行地址,而不是一条指令。

  你可以在ARM或Thumb代码中编写异常处理函数。CP15 SCTLR.TE位被用于指定异常处理函数是否会使用ARM或Thumb。当异常处理时,先前处理器的模式、状态和寄存器必须保藏,从而使程序在异常处理之后可以恢复。

12.2 异常模式总结

  表12.1列出了中断的状态,在进入一个异常处理韩式时禁止了CPSR的I和F位。

12.2.1 异常优先级

  因为一些异常类型会同时发生,处理器为每个异常赋予一个固定的优先级。未定义指令预取中止超级用户调用由于一个指令(有为未定义模式和SVC模式位操作码的特定位模式)的执行,因而不会同时发生。因此它们具有相同的优先级。

  注意:ARM架构并未定义何时异步异常发生。因此,异步异常的优先级相对于其它优先级,同步和异步,是实现定义的。

  在异常的优先级实际异常处理代码之间作区分是重要的,这发生在多个异常同时请求时。表12-1包含一列讲述FIQ和IRQ如何自动被一些异常禁止。(所有的异常禁止IRQ,只有FIQ和复位禁止了FIQ。)这由处理器自动设置CPSR
I(IRQ)和F(FIQ)位完成。

  因此,一个FIQ异常可以中断一个中止处理函数或IRQ异常。在数据中止和FIQ同时发生时,数据中止(具有更高优先级)首先进行。这允许处理器记录数据中止的返回地址。但是因为FIQ不能被数据中止禁止,我们然后立即接受FIQ的异常。在FIQ的最后,我们返回到数据中止处理函数。

  超过一个异常可能潜在地同时发生,但是一些组合是相互排斥的。一个预取中止标记一条指令是无效的,因此不可能同时发生作为未定义指令或SVC(当然,SVC指令也不能是一条未定义指令)。这些指令不能引起任何内存访问,因此不会引起数据中止。架构未定义异步异常,FIQ,IRQ,或异步中止何时必须接受,但事实上,接受一个IRQ或数据中止异常并未禁止FIQ异常,意味着FIQ异常会相对IRQ或异步中止处理优先被考虑。

12.3 进入一个异常处理程序

  当一个异常发生时,ARM处理器自动地做下列事情:

 > 在新模式的链接寄存器(LR)中,保存下一条指令的地址

 >
拷贝CPSR到SPSR,SPSR是分组寄存器中的一个,特定于每种(非用户)操作模式。

 > 修改CPSR模式位到与异常类型相关联的一个模式。其它的CPSR模式位的值设置由CP15系统控制寄存器决定。T位由CP15的TE位设置。J位被清除,E位(字节序)设置为EE(Exception Endianness,异常字节序)位的值。这使得异常总是运行在ARM或Thumb状态,小端或大端,相对于异常前的处理器状态。

 > 强制PC指向异常向量表中相应的指令

  对于异常处理软件,在异常入口立即保存寄存器值到堆栈总是必要的。(FIQ模式具有跟多的专用寄存器,因此一个简单的处理函数可能能够以不需要使用堆栈的形式被编写。)

  一条特殊的汇编语言指令提供协助,以节省必要的寄存器,被称为SRS(Store Return State)。这条指令使得LR和SPSR进入任何模式的堆栈;使用哪个堆栈由指令操作数指定。

12.4 从异常处理程序离开

  为了从异常处理程序离开,两个独立地操作必须原子地进行:

 > 从保存的SPSR恢复CPSR

 > 设置PC为返回地址偏移

  在ARM架构中,这可以通过使用RFE指令任何以PC作为目的寄存器的标志设置数据处理操作(以S作为后缀)实现,例如,SUBS
PC,LR,#offset(注意S)。异常返回(Return From Exception,
RFE)指令
从当前模式栈内pop链接寄存器和SPSR

12.5 向量表

  表12-1中的第1列给出了与特定类型异常相关联的向量表中的向量偏移。这是ARM处理器在异常抛出时跳转的指令表。这些指令位于内存中的特定位置。正常的向量基地址是0x00000000,但是绝大多数ARM处理器允许向量基地址被移动到0xFFFF0000(或HIVECS)。所有的Cortex-A系列处理器允许这点,并且这是Linux内核选择的默认地址。实现安全扩展的处理器可以额外地设置向量基地址,分别为安全和非安全状态,使用CP15向量基地址寄存器。

  你会注意到只有一个单一字的地址与每种异常类型相关联。因此,每种异常只有一个单一的指令可以被放在向量表中(尽管,理论上,两个16位的Thumb指令可以被使用)。FIQ是不同的。因此,向量表入口几乎总是包含各种形式的分支之一。

B<label>

这执行了相对PC的分支。这对于调用在内存中足够近的异常处理代码是合适的,因为分支指令中提供的24位域足够大来编码这个偏移。

LDR PC, [PC, #offset]

从一个相对异常指令地址定义的内存位置加载PC。这让异常处理程序被放置在全32位内存空间中的任意地址(相对前面简单的分支,花费一些额外的周期)。

12.6 返回指令

  链接寄存器(LR)在异常处理之后被用于存储PC合适的返回地址。它的值需要如表12-1那样被修改,依赖于异常发生的类型。《ARM架构参考手册》(ARM Architecture
Reference Manual)
合适地定义了LR的值(这些定义来源的值,为的是早期硬件实现的方便)。

《Cortex?-A系列编程者指南(V3.0)》第12章<异常处理>笔记

时间: 2024-10-23 09:53:36

《Cortex?-A系列编程者指南(V3.0)》第12章<异常处理>笔记的相关文章

《Cortex?-A系列编程者指南(V3.0)》第13章&lt;中断处理&gt;笔记

在本章,我们会看看ARM处理器处理中断的一系列方法,简单地看看通用中断控制器(Generic Interrupt Controller,GIC)架构. 旧版本的ARM架构允许实现者在他们的外部中断控制器设计中相当大的自由,没有关于中断类型或数量,或者是被用于中断控制模块接口的软件模型的协议.GIC架构提供一个更为严格的控制规范,使得来自不同制造商之间的中断控制器之间有更高程度的一致性.这使得中断处理代码变得更加可移植. 13.1 外部中断请求 如我们在第12章的异常类型中讨论的,所有的ARM处理

【Android】12.0 第12章 Intent及其过滤器&mdash;本章示例主界面

分类:C#.Android.VS2015: 创建日期:2016-02-23 一.简介 这一章我们主要学习Intent的基本用法,并通过例子演示如下功能: 如何启动另一个界面: 如何获取另一个界面的返回值: 如何利用Intent读取图库中的图片: 如何利用Intent读取和更新通讯录: 如何利用Intent实现记事本功能. 二.本章示例主界面 1.运行截图 2.MainActivity.cs文件中对应的代码 chItems.Add(new Chapter() { ChapterName = "第1

android编程权威指南 第三版 pdf

下载地址:网盘下载 Big Nerd Ranch是美国一家专业的移动开发技术培训机构.本书主要以其Android训练营教学课程为基础,融合了几位作者多年的心得体会,是一本完全面向实战的Android编程权威指南.全书共36章,详细介绍了8个Android应用的开发过程.通过这些精心设计的应用,你可以掌握很多重要的理论知识和开发技巧,获得宝贵的开发经验. 第3版较之前版本增加了对数据绑定等新工具的介绍,同时新增了针对单元测试.辅助功能和MVVM架构等主题的章节.如果你熟悉Java语言,或者了解面向

从Cocos2d-html5 v2.2.x到Cocos2d-JS v3.0 alpha2升级指南

1. 事件管理机制 1.1 在2.2.2版中分散的事件分发器cc.TouchDispatcher, cc.MouseDispatcher, cc.KeyboardDispatcher, cc.AccelerometerDispatcher的所有功能都已经被合并到cc.eventManager,所以事件(鼠标,触摸,键盘,陀螺仪, 用户自定义)都将由cc.eventManager负责分发,也都将通过它进行注册. 更多关于cc.eventManager的信息可以查看这篇详细文档 1.2 由于新的事件

DeskPRO.v3.0.0.Enterprise.PHP.NULL 1CD(3维建模 CAM (计算机辅助制造)软件, 致力于尽可能快地建立3维立体模型并将 之转变成CNC数控机床能用的数据)

DDS产品: FEMtools.v3.3.Win32 1CD(振动灵敏度分析软件) FEMtools.v3.3.Win64 1CD Network Analysis Inc产品: Sinda/G.Application.Suite.v2.6 Working-ISO 1CD(有限差分析器软件) ECS产品: FemFat v4.7C 1CD(用于对部件进行疲劳测试的软件.它可为部件的安全使用提供快速可信的解决方案,并可结合NASTRAN,ABAQUS,ANSYS,I-DEAS,MEDINA,PAT

知道创宇研发技能表v3.0

2015/8/21 发布 by @知道创宇(www.knownsec.com) @余弦 & 404团队 后续动态请关注微信公众号:Lazy-Thought 说明 关于知道创宇 知行合一 | 守正出奇 知道创宇是一家黑客文化浓厚的安全公司,愿景是让互联网更好更安全 本技能表为知道创宇研发工程师的技能树集合,是的,很庞大 聪明的人,会根据每个tip自驱动扩展 不聪明的人,坐等别人手把手,不仅不适合知道创宇,也不适合任何有极客精神的公司 附件标志是我们推荐的附加资源,感谢资源提供者 知道创宇研发技能表

编程入门指南

前言 如今编程成为了一个越来越重要的「技能」:作为设计师,懂一些编程可能会帮你更好地理解自己的工作内容:作为创业者,技术创始人的身份则会让你的很多工作显得更容易.而作为刚想入门的新手,面对眼前海量的信息,或许根本不知道从哪里开始:入门轻松度过初级材料的学习后,发现学习越来越困难,陡峭的学习曲线又让你望而却步:你知道如何在页面上打印输出一些文本行,但是你不知道何时该进行一个真正的有用的项目:你不清楚自己还有哪些不知道的东西,你甚至搞不清下一步该学什么. 这篇文章的内容对此不仅会有一些方向性的建议,

Swift 编程风格指南(raywenderlich.com 版本)

官方 raywenderlich.com Swift 编程风格指南 本文版权归 raywenderlich.com .The Official raywenderlich.com Swift Style Guide项目以及所有贡献者所有.译者翻译仅供知识传播使用. 本风格指南的目标是让Swift代码更简洁.可读更强. 语言 推荐使用跟苹果API文档风格统一的英语. 推荐: var color = "red" 不推荐: var colour = "red" 空白 使用

ARM linux电源管理——Cortex A系列CPU(32位)睡眠和唤醒的底层汇编实现

ARM linux电源管理——Cortex A系列CPU(32位)睡眠和唤醒的底层汇编实现 承接 http://www.wowotech.net/pm_subsystem/suspend_and_resume.html Linux电源管理(6)_Generic PM之Suspend功能一文中的下图. 本文主要分析平台相关的CPU睡眠和唤醒,即下电和上电流程,以及ARM底层汇编代码实现. 内核版本:3.1.0               CPU:ARM Cortex-A7 1 平台相关函数执行流程