linux中swi指令,ARM中的SWI指令(转)

在需要软件中断处调用

__SWI  0xNum           ;Num为SWI中断处理模块的编号,见表SwiFunction

;软件中断

SWI_Exception_Function

CMP     R0, #12 ;R0中的SWI编号是否大于最大值

/* 下面这句语句把 (LDRLO这条指令的地址+8+ R0*4) 的地址装载到PC寄存器,举例如果上面的 Num="1",也就是R0 =

1, 假设LDRLO这条指令的地址是0x00008000,那么根据ARM体系的3级流水线 PC寄存器里指向是下两条指令 于是PC =

0x00008008  也就是伪指令DCD TASK_SW 声明的标号TASK_SW  的地址,注意DCD TASK_SW 这条指令本身不是ARM能执行的指令,也不会占有地址,这条指令靠汇编器汇编成可执行代码,它的意义就是声明

TASK_SW的地址,  , [PC, R0, LSL #2] 这个寻址方式就是 PC + R0的值左移2位的值( 0x01<<2

=> 0x04 ),这样PC的值就是0x0000800C, 即ENTER_CRITICAL的地址于是ARM执行该标号下的任务 */

LDRLO   PC, [PC, R0, LSL #2]

MOVS    PC, LR;返回

SwiFunction

DCD     TASK_SW                ;0

DCD     ENTER_CRITICAL         ;1

DCD     EXIT_CRITICAL            ;2

DCD     ISRBegin                 ;3

DCD     ChangeToSYSMode         ;4

DCD     ChangeToUSRMode         ;5

DCD     __OSStartHighRdy        ;6

DCD     TaskIsARM               ;7

DCD     TaskIsTHUMB             ;8

DCD     OSISRNeedSwap           ;9

DCD     GetOSFunctionAddr       ;10

DCD     GetUsrFunctionAddr      ;11

TASK_SW

MRS     R3, SPSR                        ;保存任务的CPSR

MOV     R2, LR                          ;保存任务的PC

MSR     CPSR_c, #(NoInt | SYS32Mode)    ;切换到系统模式

STMFD   SP!, {R2}                       ;保存PC到堆栈

STMFD   SP!, {R0-R12, LR}               ;保存R0-R12,LR到堆栈

;因为R0~R3没有保存有用数据,所以可以这样做

B       OSIntCtxSw_0                    ;真正进行任务切换

ENTER_CRITICAL

;OsEnterSum++

LDR     R1, =OsEnterSum

LDRB    R2, [R1]

ADD     R2, R2, #1

STRB    R2, [R1]

;关中断

MRS     R0, SPSR

ORR     R0, R0, #NoInt

MSR     SPSR_c, R0

MOVS    PC, LR

================================================================================

备忘如下:

1、触及SWI软中断,就不能不说ATPCS过程调用,将后续日志记录;

2、SWI异常一旦触发,内核硬件完成:

进入Supervisor模式;

拷贝CPSR至SPSR_svc

拷贝异常返回地址至LR_svc

将0x00000008装入PC

因此,当触发SWI软中断前内核处于Supervisor模式,SPSR_svc、LR_svc中的值将被破坏;

3、SWI指令编码中自带24bit数据作为软中断号(swi_num),因此可通过取SWI指令编码获取软中断号;LDR r0,[lr,#-4]就是这样;

4、SWI_Exception_Function函数一般采用C编码(也可汇编),采用C编码可直接套用switch根据swi_nun软中断号切换,SWI_Exception_Function函数的编制是灵活的,比如可以为带参或不带参函数;

5、一个SWI调用允许带1~4个字型参数和1~4个字型返回值,触发SWI调用时四个参数依次保存在R0~R3中,返回值也存于R0~R3内,这和ATPCS函数调用一致;

6、在C中声明一个典型的无参无返回值的SWI调用为:”__swi(0x00)

void

IRQEnable();“这样随时都可以使用”IRQEnable();“触发一个软中断(中断号0),其允许IRQ中断的功能必须在

SWI_Exception_Function软中断处理函数中实现;

8、最后须要注意的:SP堆栈指针时为间接寻址,”MOV r1,sp“指令将R1也变成一个指针,其存放的内容为R0在RAM中的地址而非R0值;

9、还有一点:SWI调用带参和SWI_Exception_Function函数的带参,是两回事,SWI调用带参是指的是调用多少号软中断,SWI_Exception_Function函数是函数(软中断运行的参数)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值