本节首要介绍编写SWI处理程序时需求留意的几个问题,包含判别SWI中止号,运用汇编言语编写SWI反常处理函数,运用C言语编写SWI反常处理函数,在特权形式下运用SWI反常中止处理,从应用程序中调用SWI。
1.判别SWI中止号
当产生SWI反常,进入反常处理程序时,反常处理程序有必要提取SWI中止号,然后得到用户恳求的特定SWI功用。
在SWI指令的编码格局中,后24位称为指令的“comment field”。该域保存的24位数,即为SWI指令的中止号,如图7-4所示。
榜首级的SWI处理函数经过LR寄存器内容得到SWI指令地址,并从存储器中得到SWI指令编码。一般这些作业经过汇编言语、内嵌汇编来完结。下面的比如显现了提取中止向量号的规范进程。
.SWI_Handler:
STMFD sp!,{r0-r12,lr};保存寄存器
LDR r0,[lr,#-4];核算SWI指令地址
BIC r0,r0,#0xff000000;提取指令编码的后24位
;
; 提取出的中止号放r0寄存器,函数回来
;
LDMFD sp!, {r0-r12,pc}^;康复寄存器
在这个比如中,运用LR-4得到SWI指令的地址,再经过“B%&&&&&% r0, r0, #0xff000000”指令提取SWI指令中止号。
2.运用C言语编写SWI反常处理函数
尽管榜首级SWI处理函数(完结中止向量号的提取)有必要用汇编言语完结,但第二级中止处理函数(依据提取的中止向量号,跳转到详细处理函数)却能够运用C言语来完结。
由于榜首级的中止处理函数现已将中止号提取到寄存器r0中,所以依据AAPCS函数调用规矩,能够直接运用BL指令跳转到C言语函数,并且中止向量号作为榜首个参数被传递到C函数。例如,汇编中运用了“BL C_SWI_Handler”跳转到C言语的第二级处理函数,而第二级的C言语函数示例如下。
void C_SWI_handler (unsigned number)
{
switch (number)
{
case 0 : /* SWI number 0 code */
break;
case 1 : /* SWI number 1 code */
break;
…
default : /* Unknown SWI – report error */
}
}
别的,假如需求传递的参数多于1个,那么能够运用仓库,将仓库指针作为函数的参数传递给C类型的二级中止处理程序,就能够实现在两级中止之间传递多个参数。
例如:
MOV r1, sp;将传递的第二个参数(仓库指针)放到r1中
BL C_SWI_Handler;调用C函数
相应的C函数的进口变为:
void C_SWI_handler(unsigned number, unsigned *reg)
一起,C函数也能够经过仓库回来操作的成果。
3.从应用程序中调用SWI
可从汇编言语或 C/C++ 中调用 SWI。
从汇编言语程序中调用SWI,只需遵从AAPCS规范即可。调用前,设定一切必需的值并宣布相关的 SWI。例如:
MOV r0, #65 ; 将软中止的子功用号放到r0中
SWI 0x0
留意:
SWI指令和其他一切ARM指令相同,能够被条件履行。