预览加载中,请您耐心等待几秒...
1/4
2/4
3/4
4/4

在线预览结束,喜欢就下载吧,查找使用更方便

如果您无法下载资料,请参考说明:

1、部分资料下载需要金币,请确保您的账户上有足够的金币

2、已购买过的文档,再次下载不重复扣费

3、资料包下载后请先用软件解压,在使用对应软件打开

arm软件中断的方法介绍 SWI指令---软件中断实例详解 关键字:SWI,指令,软件中断,实例,详解 SWI,即softwareinterrupt软件中断。该指令产生一个SWI异常。意思就是处理器模式改变为超级用户模式,CPSR寄存器保存到超级用户模式下的SPSR寄存器,并且跳转到SWI向量。其ARM指令格式如下: SWI{cond}immed_24 Cond域:是可选的条件码(参见ARM汇编指令条件执行详解). immed_24域:范围从0到224-1的表达式,(即0-16777215)。用户程序可以使用该常数来进入不同的处理流程。 一、方法1:获取immed_24操作数。 为了能实现根据指令中immed_24操作数的不同,跳转到不同的处理程序,所以我们往往需要在SWI异常处理子程序中去获得immed_24操作数的实际内容。获得该操作数内容的方法是在异常处理函数中使用下面指令: LDRR0,[LR,#-4] 该指令将链接寄存器LR的内容减去4后所获得的值作为一个地址,然后把该地址的内容装载进R0。此时再使用下面指令,immed_24操作数的内容就保存到了R0: BICR0,R0,#0xFF000000 该指令将R0的高8位清零,并把结果保存到R0,意思就是取R0的低24位。 可能还是有人会问:为什么在SWI异常处理子程序中执行这两条指令后,immed_24操作数的内容就保存到了R0寄存器呢?之所以会有这样的疑问,基本都是因为对LR寄存器的作用没了解清楚。下面介绍一下链接寄存器LR(R14)的作用。 寄存器R14(LR寄存器)有两种特殊功能: ·在任何一种处理器模式下,该模式对应的R14寄存器用来保存子程序的返回地址。当执行BL或BLX指令进行子程序调用时,子程序的返回地址被放置在R14中。这样,只要把R14内容拷贝到PC中,就实现了子程序的返回(具体的子程序返回操作,这里不作详细介绍)。 ·当某异常发生时,相应异常模式下的R14被设置成异常返回的地址(对于某些异常,可能是一个偏移量,一个较小的常量)。异常返回类似于子程序返回,但有小小的不同(这里不作详细介绍)。 所谓的子程序的返回地址,实际就是调用指令的下一条指令的地址,也就是BL或BLX指令的下一条指令的地址。所谓的异常的返回的地址,就是异常发生前,CPU执行的最后一条指令的下一条指令的地址。 例如:(子程序返回地址示例) 指令指令所在地址 ADDR2,R1,R3;0x300000 BLsubC;0x300004 MOVR1,#2;0x300008 BL指令执行后,R14中保存的子程序subC的返回地址是0x300008。 再例如:(异常返回地址示例) 指令指令所在地址 ADDR2,R1,R3;0x300000 SWI0x98;0x300004 MOVR1,#2;0x300008 SWI指令执行后,进入SWI异常处理程序,此时R14中保存的返回地址为0x300008。 所以,在SWI异常处理子程序中执行LDRR0,[LR,#-4]语句,实际就是把产生本次SWI异常的SWI指令的内容(如:SWI0x98)装进R0寄存器。又因为SWI指令的低24位保存了指令的操作数(如:0x98),所以再执行BICR0,R0,#0xFF000000语句,就可以获得immed_24操作数的实际内容。 二、方法2:使用参数寄存器。 实际上,在SWI异常处理子程序的实现时,还可以绕开immed_24操作数的获取操作,这就是说,我们可以不去获取immed_24操作数的实际内容,也能实现SWI异常的分支处理。这就需要使用R0-R4寄存器,其中R0-R4可任意选择其中一个,一般选择R0,遵从ATPCS原则。 具体方法就是,在执行SWI指令之前,给R0赋予某个数值,然后在SWI异常处理子程序中根据R0值实现不同的分支处理。例如: 指令指令所在地址 MOVR0,#1;#1给R0 SWI0x98;产生SWI中断,执行异常处理程序SoftwareInterrupt ADDR2,R1,R3; ;SWI异常处理子程序如下 SoftwareInterrupt CMPR0,#6;ifR0<6 LDRLOPC,[PC,R0,LSL#2];ifR0<6,PC=PC+R0*4,elsenext MOVSPC,LR SwiFunction DCDfunction0;0 DCDfunction1;1 DCDfunction2;2 DCDfunction3;3 DCDfunction4;4 DCDfunction5;5 Function0 异常处理分支0代码 Function1 异常处理分支1代码 function2 异常处理分支2代码 function3 异常处理分支3代码 function4 异常处理分支4代码 funct