转载于:http://book.2cto.com/201209/4625.html
-
1.SVC
SVC(Supervisor Call)指令用于产生一个SVC异常。它是用户模式代码中的主进程,用于创造对特权操作系统代码的调用。SVC是用于呼叫操作系统所提供API的正道。用户程序只需知道传递给操作系统的参数,而不必知道各API函数的地址。
SVC指令带一个8位的立即数,可以视为是它的参数,被封装在指令自身,如:
SVC 3; 呼叫3号系统服务
则3被封装在这个SVC指令中。因此在SVC服务例程中,需要读取本次触发SVC异常的SVC指令,并提取出8位立即数所在的位段,从而判断系统调用号,工作流程如图7-7所示。
实现上图功能的代码如下所示:
svc_handler
TST LR, #0x4; ;测试EXC_RETURN的比特2
ITE EQ; ;如果为0
MRSEQ R0, MSP; ;则使用的是主堆栈,故把MSP的值取出
MRSNE R0, PSP; ;否则,使用的是进程堆栈,故把PSP的值取出
LDR R1, {R0,#24}; ;从栈中读取PC值
LDRB R0, {R1,#-2}; ;从SVC指令中读取立即数放到R0
; 准备调用系统服务函数。这需要适当调整入栈的PC值及LR(EXC_RETURN)来进入OS内部
BX LR; ;借异常返回的形式,进入OS内部,最终调用系统服务函数一旦获取了调用号,就可以用它来调用系统服务函数了。有理由相信,操作系统应该使用TBB/TBH查表跳转指令来加速定位正确的服务函数。然而,如果读者是设计OS的人员,则必须检查这个参数的合法性,以免因数字超出跳转表的范围而跳飞。因为不能在SVC服务例程中嵌套使用SVC,所以如果有需要,就要直接调用SVC函数,如使用BL指令。
2.PendSV
PendSV是为系统级服务提供的中断驱动。在一个操作系统环境中,当没有其他异常正在执行时,可以使用PendSV来进行上下文的切换。
在进入PendSV处理函数时:
(1)xPSR、PC、LR、R12、R0~R3已经在处理栈中被保存。
(2)处理模式切换到线程模式。
(3)栈是主堆栈。
由于PendSV在系统中被设置为最低优先级,因此只有当没有其他异常或者中断在执行时才会被执行。