软中断
:
编程异常通常叫做软中断
软中断是通讯进程之间用来模拟硬中断的
一种信号通讯方式。
中断源发中断请求或软中断信号后,CPU
或接收进程在适当的时机自动进行中断
处理或完成软中断信号对应的功能
软中断是软件实现的中断,也就是程序运行时其他程序对它的中断;而硬中断是硬件实现的中断,是程序运行时设备对它的中断。
1.
软中断发生的时间是由程序控制的,
而硬中断发生的时间是随机的
2.
软中断是由程序调用发生的,
而硬中断是由外设引发的
3.
硬件中断处理程序要确保它能快速地完成它的任务,
这样程序执行时才不会等待较长时间
SWI : 软件中断
(S
oftw
are
I
nterrupt)
SWI{条件} <24 位编号>
指令格式 这是一个简单的设施,但可能是最常用的。多数操作系统设施是用 SWI 提供的。没有 SWI 的 RISC OS 是不可想象的。
Nava Whiteford 解释了 SWI 是如何工作的(最初在 Frobnicate issue 12½)...
SWI 是什么?
SWI 表示 Software Interrupt。在 RISC OS
中使用 SWI
来访问操作系统例程或第三方生产的模块。许多应用使用模块来给其他应用提供低层外部访问。
SWI 的例子有:
- 文件器 SWI,它辅助读写磁盘、设置属性等。
- 打印机驱动器 SWI,用来辅助使用打印并行端口。
- FreeNet/Acorn TCP/IP 协议栈 SWI,用 TCP/IP 协议在 Internet
上发送和接收数据。
在以这种方式使用的时候,SWI
允许操作系统拥有一个模块结构,这意味着用来建立完整的操作系统的所需的代码可以被分割成许多小的部分(模块)和一个模块处理程序(handler)。
当 SWI 处理程序得到对特定的例程编号的一个请求的时候,它找到这个例程的位置并执行它,并传递(有关的)任何数据。
它是如何工作的?
首先查看一下如何使用它。一个 SWI 指令(汇编语言)看起来如下:
SWI &02
或
SWI "OS_Write0"
这些指令实际上是相同的,将被汇编成相同的指令。唯一的不同是第二个指令使用一个字符串来表示 SWI 编号
&02。在使用采用了字符串编号的程序的时候,在执行之前首先查找这个字符串。
在这里我们不想处理字符串,因为它不能给出它要进行什么的一个真实表示。它们通常用于增进一个程序的清晰程度,但不是实际执行的指令。
让我们再次看一下第一个指令:
SWI &02
这是什么意思? 字面的意思是进入 SWI 处理程序并传递值 &02。在 RISC OS
中这意味着执行编号是 &02 的例程。
它是如何这么作的? 它如何传递 SWI 编号和进入 SWI 处理程序?
如果你查看内存的开始 32 字节(位于 0-&1C)并反汇编它们(查开实际的 ARM
指令)你将见到如下:
地址 内容 反汇编 00000000 : 0..å :
E5000030 : STR R0,[R0,#-48] 00000004 : .óŸå : E59FF31C : LDR
PC,&00000328 00000008 : .óŸå : E59FF31C : LDR
PC,&0000032C 0000000C : .óŸå : E59FF31C : LDR
PC,&00000330 00000010 : .óŸå : E59FF31C : LDR
PC,&00000334 00000014 : .óŸå : E59FF31C : LDR
PC,&00000338 00000018 : .óŸå : E59FF31C : LDR
PC,&0000033C 0000001C : 2?ã : E3A0A632 : MOV
R10,#&3200000
让我们仔细看一下。
除了第一个和最后一个指令之外(它们是特殊情况)你见到的都是把一个新值装载到 PC
(程序计数器)的指令,它们告诉计算机到哪里去执行下一个指令。还展示了这个值是从内存中的一个地址接受来的。(你可以在 !Zap
主菜单上使用“Read Memory”选项去自己查看一下。)
这看起来好象与 SWI 没多少关系,下面做进一步的说明。
一个 SWI 所做的一切就是把模式改变成超级用户并设置 PC 来执行在地址 &08
处的下一个指令! 把处理器转换到超级用户模式会切换掉两个寄存器 r13 和 r14 并用 r13_svc 和 r14_svc
替换它们。
在进入超级用户模式的时候,还把 r14_svc 设置为在这个 SWI 指令之后的地址。
这个实际上就象一个连接到地址 &08 的分支指令(BL
&08),但带有用于一些数据(SWI 编号)的空间。
象我说过的那样,地址 &08 包含跳转到另一个地址的一个指令,就是实际的 SWI
程序的地址!
此时你可能会想“稍等一会! 还有 SWI 编号呢?”。实际上处理器忽略这个值本身。SWI 处理程序使用传递来的 r14_svc
的值来获取它。
下面是完成它的步骤(在存储寄存器 r0-r12 之后):
- 它从 r14 中减去 4 来获得 SWI 指令的地址。
- 把这个指令装载到一个寄存器。
- 清除这个指令的高端 8 位,去掉了 OpCode 而只剩下的 SWI 编号。
- 使用这个值来找到要被执行的代码的例程的地址(使用查找表等)。
- 恢复寄存器 r0-r12。
- 使处理器离开超级用户模式。
- 跳转到这个例程的地址。
容易吧! ;)
下面是一个例子,来自 ARM610 datasheet:
0x08 B Supervisor
EntryTable
DCD ZeroRtn
DCD ReadCRtn
DCD WriteIRtn
...
Zero EQU 0
ReadC EQU 256
WriteI EQU 512
; SWI 包含需要的例程在位 8-23 中和数据(如果有的话)在位 0-7 中。
; 假定 R13_svc 指向了一个合适的栈
STMFD R13, {r0-r2 , R14}
; 保存工作寄存器和返回地址。
LDR R0,[R14,#-4]
; 得到 SWI 指令。
BIC R0,R0, #0xFF000000
; 清除高端的 8 位。
MOV R1, R0, LSR #8
; 得到例程偏移量。
ADR R2, EntryTable
; 得到入口表(EntryTable)的开始地址。
LDR R15,[R2,R1,LSL #2]
; 分支到正确的例程
WriteIRtn
; 写 R0 中的位 0 - 7 中的字符。
.............
LDMFD R13, {r0-r2 , R15}^
; 恢复工作空间,并返回、恢复处理器模式和标志。
这就是 SWI 指令的基本处理步骤。
分享到:
相关推荐
ARM SWI 软中断介绍,模式切换,可以学习一下
s3c2410软中断程序,用来测试s3c2410软中断是否可行,我的开发环境是gt2440
软中断示例代码,贴出来跟大家共享。希望大家喜欢
ADS环境下软中断实现64位整数加法 运行于arm920T
ARM汇编实现软中断,用ADS编写。先调用Init装中断,再跳转到SWIhandler,SWIhandler为中断服务程序
一个自己改写的ARM的软件中断程序,对理解SWI很有帮助,祝君成功!
通过SWI异常中断指令,在用户模式下应用程序可以调用系统模式下的代码,在操作系统中表现为系统调用,那这个过程又是如何实现的呢?带着疑问让我们来学习吧!
在s3c2440开发板裸板上模拟软中断处理程序,处理程序中是对LED灯的控制。
平台44B0开发板,里面包含一个bootloader程序,由此连接一个led灯控制程序,可以直接生成bin文件,实现烧写,非调制版,实现软中断和bootloader启动初始化
中断实验完整源码,里面有一个完整的中断实验
arm9软中断的一个例子。。。。想要了解swi软中断详细处理过程的朋友可以下
SWI异常02
汇编语言里设置软中断,来调用c语言函数。实现系统调用的模拟。
ARM处理器软中断处理。a_swi.s文件是最开始处理的SWI句柄,用ARM汇编指令编写。c_swi.c文件是在执行a_swi.s文件之后调用执行的C语言SWI句柄。
用ADS编译测试通过,裸机ARM软中断测试程序,可以通过uboot下载至NAND里运行,直接下载到SDRAM无法运行(因为没有开启MMU)。 http://blog.csdn.net/forsakening/article/details/9004812这里是我对代码及arm软中断的...
SWI异常01SWI异常01
CCS开发环境下,在HWI硬件中断服务中启动SWI软件中断线程的源码,适合学习软件&硬件中断
在ARM平台上设计的针对任意64位数数据的加法程序,采用汇编和C混合实现,结合软中断实现。
SWI Example
swi program for keil example