Chinaunix首页 | 论坛 | 博客
  • 博客访问: 491407
  • 博文数量: 121
  • 博客积分: 4001
  • 博客等级: 上校
  • 技术积分: 1390
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-13 21:48
文章分类

全部博文(121)

文章存档

2011年(4)

2010年(11)

2009年(106)

我的朋友

分类: 嵌入式

2009-09-22 13:41:36

通过SWI异常中断指令,在用户模式下应用程序可以调用系统模式下的代码,在操作系统中表现为系统调用,
那这个过程又是如何实现的呢?带着疑问让我们来学习吧!

    在SWI指令中包括一个24位的立即数(中断调用号),该立即数指示了用户要请求的特定的调用功能,所以在SWI的异常中断中要读取这个中断调用号,然后根据中断号,来调用相应的处理程序。这个过程可以分两个步骤:

1.SWI异常中断处理程序
由于是在底层操作所以这个异常中断处理程序得用汇编语言编写,描述如下:

area top_swi code readonly
export swi_headler
swi_headler
stmfd sp!, {r0-r12, lr}          ; 保存r0至r12,lr的寄存器值
ldr r0, [lr, #-4]                      ; 从存储器中取得SWI指令的所在地址
bic r0, r0, #FF000000            ; 读取24位中断调用号
mov r1, sp
;================================================
bl swi_service_func                  ; 调用功能服务函数,见下面
                                             ; 中断调用号通过r0寄存器传入
                                             ; 参数通过r1寄存器传入
;================================================
ldmfd sp!, {r0-r12, pc}^   ;恢复调用前的r0至r12,离开中断处理程序
end

2.功能服务程序
编写利用从中断处理函数获得的中断调用号我们可以写出如下服务函数(为了简单我们用C语言)
void swi_service_func(unsigned int number, unsigned int *reg)
{
    unsigned int reg1, reg2, reg3, reg4;
    //获取SWI前传入的参数
    reg1 = reg[0];
    reg2 = reg[1];
    reg3 = reg[2];
    reg4 = reg[3];
    switch (number) {
        case 0:
            // do something
        break;
       
        case 1:
            // do something
        break;
        .
        .
        .
        case n:
            // do something
        break;
       
        default:
            // do something
        }
    }
    // 更新结果存入r0-r3
    reg[0] = updata_reg1;
    reg[1] = updata_reg2;
    reg[2] = updata_reg3;
    reg[3] = updata_reg4;
}
阅读(1864) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~