中断与异常

摘要:
C恢复站点--------------------------------------------异常向量表--------------------------------------------。globl_ start_ start:CPU跳转到此地址以执行指令**假设地址为0x18**ldrpc:然后CPU最终跳转到execute__ Irq代码//保护场景:为什么不使用b指令实现中断跳转:

arm对异常(中断)处理过程

1 初始化:
:: a 设置中断源,让它可以产生中断
:: b 设置中断控制器(可以屏蔽某个中断,优先级)
:: c 设置CPU总开关,(使能中断)

2 执行其他程序:正常程序

3 产生中断:按下按键--->中断控制器--->CPU

4 cpu每执行完一条指令都会检查有无中断/异常产生

5 发现有中断/异常产生,开始处理。对于不同的异常,跳去不同的地址执行程序。这地址上,只是一条跳转指令,跳去执行某个函数(地址),这个就是异常向量。如下就是异常向量表,对于不同的异常都有一条跳转指令。  (3-5都是硬件强制做的)

6 这些函数做什么事情?
:: 软件做的:
:: a 保存现场(各种寄存器)
:: b 处理异常(中断):
:::: 分辨中断源
:::: 再调用不同的处理函数
:: c 恢复现场

--------------------------------------异常向量表-------------------------------------

.globl _start
_start: b   reset
    ldr pc, _undefined_instruction
    ldr pc, _software_interrupt
    ldr pc, _prefetch_abort
    ldr pc, _data_abort
    ldr pc, _not_used
    ldr pc, _irq //发生中断时,CPU跳到这个地址执行该指令 **假设地址为0x18**
    ldr pc, _fiq
//我们先在0x18这里放 ldr pc ,__irq,于是cpu最终会跳去执行__irq代码
//保护现场,调用处理函数,恢复现场

思考:为什么不用b指令实现中断的跳转?

软中断程序:

示例一:

.text
    
    @异常向量表
    b     reset        @0x00 reset
    nop                @0x04 udef
    b    swi_handler   @0x08 swi
    nop                @0x0c prefetch abort 指令预取终止
    nop                @0x10 data abort 数据访问终止
    nop                @0x14 reserved   保留
    nop                @0x18 irq
    nop                @0x1c fiq
                       @nop 占空地址;0x00-1c为异常向量表所用,不可被其他语句所占
swi_handler:
    stmfd sp!,{r0,lr} @将r0,lr进栈,保护现场,sp为堆栈指针
    mov r0,#6
    ldmfd sp!,{r0,pc} @将原值出栈到r0,pc,恢复现场

reset:
    mov r0,#3
    swi 2
    
    mov r1,r0
    b   reset
    

执行压栈和出栈指令后报错

中断与异常第1张

 所以在压栈之前,要令堆栈指针sp重新指向一个空间

    .text
    
    @异常向量表
    b     reset      @0x00 reset
    nop             @0x04 udef
    b    swi_handler @0x08 swi
    nop                @0x0c prefetch abort 指令预取终止
    nop                @0x10 data abort 数据访问终止
    nop                @0x14 reserved   保留
    nop                @0x18 irq
    nop                @0x1c fiq
                    @nop 占空地址;0x00-1c为异常向量表所用,不可被其他语句所占
swi_handler:
    stmfd  sp!,{r0,lr} @将r0,lr进栈,保护现场,sp为堆栈指针
    mov    r0,#6
    ldmfd  sp!,{r0,pc} @将原值出栈到r0,pc,恢复现场

reset:
    ldr    sp,=stack_base
    mov    r0,#3
    swi    2
    mov    r1,r0
    b      reset
    
    .data
buf:
    .space    32   @定义内存空间,将空间末地址赋给sp
stack_base:      @开始压栈,sp递减,入栈sp递增,又会回到此位置

    .end

软中断主要用于系统调用,用于从用户空间到内核空间的切换。user--->svc

@异常向量表
    b     reset           @0x00 reset 指令机器码存放的地址空间大小有限制,可以如下单独构造4字节的空间存放
    ldr  pc,_udef        @0x04 udef
    ldr     pc,_swi         @0x08 swi   不使用b而使用ldr跳转以突破32M空间限制
    ldr  pc,_prefetch     @0x0c prefetch abort 指令预取终止
    ldr  pc,_data_abort     @0x10 data abort 数据访问终止
    nop                     @0x14 reserved   保留
    ldr  pc,_irq         @0x18 irq
    ldr  pc,_fiq         @0x1c fiq
                         @nop 占空地址;0x00-1c为异常向量表所用,不可被其他语句所占

_udef:
    .word    udef_handler
_swi:                     @此标号为地址
    .word    swi_handler  @里面存放了一个数,此数存放了地址,通过ldr将函数地址赋给PC以实现跳转
_prefetch:
    .word   prefetch_handler  @未实现
_data_abort:
    .word   data_abort_handler
_irq:
    .word   irq_handler
_fiq:
    .word   fiq_handler
swi_handler:
    stmfd  sp!,{r0,lr}   @将r0,lr进栈,保护现场,sp为堆栈指针
    sub       r0,lr,#4
    ldr    r0,[r0]
    bic    r0,#0xff000000
    bl     swi_num_handler
    ldmfd  sp!,{r0,pc}^  @将原值出栈到r0,pc,恢复现场

swi_num_handler:
    @swith(num)
    @case 2:
    @  .....
    @case 3:
    @  .....
    

reset:
    ldr    sp,=stack_base
    @切换到应用程序空间
    msr    cpsr,#0x10
    mov    r0,#3
    @ open  read  write  ioctl ...通过系统调用访问内核数据
    @  2     4      6      7      软中断号  
    swi    2     @跳转到异常向量表的软中断入口
                 @保存返回的地址到LR
                 @切换到SVC模式
    mov    r1,r0
    b      reset
    
    .data
buf:
    .space    32   @定义内存空间,将空间末地址赋给sp
stack_base:      @开始压栈,sp递减,入栈sp递增,又会回到此位置


    .end

免责声明:文章转载自《中断与异常》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇ArcGis连接oracle、oracle配置Failed to bind properties under 'spring.datasource' to javax.sql.DataSource:下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

获取,修改进程命令行

在XDebug的源码学习中看到的命令行操作,将主要源码摘录出来做了个获取和更改进程命令行的Demo. 0x01  获取命令行      这里获取命令行的方式并不是通过调用GetCommandLine函数。    而是借由ntdll中的NtQueryInformationProcess函数查询ProcessBasicInformation,得到Process...

node.js版本管理

Node安装Node的安装需要依赖很多,如gcc等,首先我们需要将这些安装成功,用rpm命令查看下,果然我们并没有gcc等,所以要用yum进行安装(基于centos6.9版本): yum -y install gcc gcc-c++ kernel-devel 将依赖安装后,我们就可以进行Node的安装啦(我是直接安在了root目录下):来到安在目录 wge...

Nginx基础06:location语法

location语法:表示uri方式定位 基础语法有三种: location = pattern{}  精准匹配 location pattern{}  一般匹配 location ~ pattern{} 正则匹配 location正则表达式: "~ xxx":匹配访问的请求的URL中必须包含"xxx" "~* xXx":匹配忽略后面"xXx"是否大...

Linux系统下Java 转换Word到PDF时,结果文档内容乱码的解决方法

本文分享在Linux系统下,通过Java 程序代码将Word转为PDF文档时,结果文档内容出现乱码该如何解决。具体可参考如下内容: 1.问题出现的背景 在Windows系统中,使用Spire.Doc for Java将Word文档转换为PDF格式时(如下代码),结果文档内容正常;但是在Linux系统中,转出来PDF文档出现乱码或方框。 import com...

python连接mysql的驱动

对于py2.7的朋友,直接可以用MySQLdb去连接,但是MySQLdb不支持python3.x。这是需要注意的~ 那应该用什么python连接mysql的驱动呢,在stackoverflow上有人解答: (1)可以尝试使用PyMySQL,但它很慢,最新的版本可以支持python 3.4. 地址:http://www.pymysql.org/ (2)还可以...

HTML页面使用layer弹出框输入数据

javascript中layer是一款近年来备受青睐的web弹层组件,layer.open对弹出框进行输入信息,并处理返回结果。详细介绍http://layer.layui.com/部署:将layer.js文件和skin目录复制到项目的./static/js目录中,在页面中引用js/layer.js <script >function add_...