ARM8 异常处理 电脑版发表于:2024/7/11 21:46 ![](https://img.tnblog.net/arcimg/hb/6930d1439f4b43e785a433685b813262.png) >#ARM8 异常处理 [TOC] ARM8 异常向量表 ------------ ![](https://img.tnblog.net/arcimg/hb/fdc10e85ce6c4ad5bc19358e0b4e61bf.png) tn2>ARMv8 异常向量表分类 4大类(Execution Levels) EL3(Exception Level 3): 安全监控模式,通常用于安全监控代码。 EL2(Exception Level 2): Hypervisor模式,用于虚拟化管理。 EL1(Exception Level 1): 内核模式,操作系统内核运行在该模式。 EL0(Exception Level 0): 用户模式,应用程序运行在该模式。 <br/> 每类下的4种具体情况 对于每个执行级别,异常向量表分为以下4种具体情况: Synchronous Exception(同步异常): 例如指令未定义、指令中止、数据中止等。 IRQ(Interrupt Request): 普通中断。 FIQ(Fast Interrupt Request): 快速中断。 SError(System Error): 系统错误。 ### 简单代码示范 ```bash adr x0,vectors // 读取异常向量表的首地址 msr vbar_el1,x0 // 设置异常表的基地址 svc #2 // 系统调用(触发同步异常陷入,sp_el进入不同的异常) 类似swi指令 ``` ### 设置异常处理简单案例 ```bash .globl _start // 声明_start为全局符号,程序的入口点 _start: mrs x1, SPSel // 将当前SP选择状态加载到x1 mrs x2, CurrentEL // 将当前异常级别加载到x2 mov x0, #0 // 将0加载到x0 //msr SPSel, x0 // 可选:将x0的值写入SPSel寄存器 mov x0, #0x5 // 将0x5加载到x0 adr x0, vectors // 获取vectors标签的地址并加载到x0 msr vbar_el1, x0 // 设置向量基址寄存器vbar_el1为x0的值 svc #0x02 // 触发系统调用 reset_end: b reset_end // 进入无限循环,保持在reset_end标签 do_bad_sync: mov x2, #1 // 将1加载到x2,表示同步异常 b reset_end // 跳转到reset_end,进入无限循环 do_bad_irq: mov x2, #2 // 将2加载到x2,表示IRQ异常 b reset_end // 跳转到reset_end,进入无限循环 .align 11 // 2^11 = 2048字节对齐,整个异常向量表2K对齐 // 16个异常,每个异常32条指令,16*32*4=2048 // 16个异常,这里使用前8个 vectors: // ===============sp0=============== // ---同步异常 .align 7 // 2^7 = 128字节对齐 mov x0, #1 // 将1加载到x0 b do_bad_sync // 跳转到do_bad_sync处理例程 // ---irq异常 .align 7 // 2^7 = 128字节对齐 mov x0, #1 // 将1加载到x0 b do_bad_irq // 跳转到do_bad_irq处理例程 // ---fiq异常 .align 7 // 2^7 = 128字节对齐 mov x0, #1 // 将1加载到x0 b reset_end // 跳转到reset_end,进入无限循环 // ---SError异常 .align 7 // 2^7 = 128字节对齐 mov x0, #1 // 将1加载到x0 b reset_end // 跳转到reset_end,进入无限循环 // ===============sp_elx=============== // ---同步异常 .align 7 // 2^7 = 128字节对齐 mov x0, #1 // 将1加载到x0 b do_bad_sync // 跳转到do_bad_sync处理例程 // ---irq异常 .align 7 // 2^7 = 128字节对齐 mov x0, #1 // 将1加载到x0 b do_bad_irq // 跳转到do_bad_irq处理例程 // ---fiq异常 .align 7 // 2^7 = 128字节对齐 mov x0, #1 // 将1加载到x0 b reset_end // 跳转到reset_end,进入无限循环 // ---SError异常 .align 7 // 2^7 = 128字节对齐 mov x0, #1 // 将1加载到x0 b reset_end // 跳转到reset_end,进入无限循环 ``` ![](https://img.tnblog.net/arcimg/hb/efef3d8e1b95431b8ca6f05472991e17.png) ![](https://img.tnblog.net/arcimg/hb/0d86a5a17cb24737a81231ba0f3f1a09.png) ![](https://img.tnblog.net/arcimg/hb/e1574f9368184404a3bb12e590f0d451.png) ![](https://img.tnblog.net/arcimg/hb/e0fb282f614c4b3abe7c4d2e12295521.png) tn2>取消`msr SPSel, x0`的注释,修改`SPSel`的值来设置偏移向的地址。 ![](https://img.tnblog.net/arcimg/hb/d307c43278844bd7af915473cdbd0f51.png)