DIY编程器网

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1018|回复: 0
打印 上一主题 下一主题

[待整理] 协处理器及其他指令之:异常产生指令

[复制链接]
跳转到指定楼层
楼主
发表于 2014-10-10 07:29:11 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
        9.5  异常产生指令

        ARM指令集中提供了两条产生异常的指令,通过这两条指令可以用软件的方法实现异常。表9.4总结了ARM异常产生指令。
         
        表9.4   RM异常产生指令
                                                                        助  记  符
                       
                                                                        含    义
                       
                                                                        操    作
                       
                                                                        SWI
                       
                                                                        软中断指令
                       
                                                                        产生软中断,处理器进入管理模式
                       
                                                                        BKPT
                       
                                                                        断点中断指令
                       
                                                                        处理器产生软件断点
                       
         
        9.5.1  软中断指令SWI

        1.指令编码格式

         
        软件中断指令SWI(Software Interrupt)用于产生软中断,从而实现从用户模式变换到管理模式,CPSR保存到管理模式的SPSR中,执行转移到SWI向量,在其他模式下也可以使用SWI指令,处理器同样切换到管理模式。
         
        指令的编码格式如图9.12所示。
       

        图9.12  SWI指令编码格式

         
        2.指令的语法格式

        SWI{<cond>}   <immed_24>
         
        ① <cond>
        为指令编码中的条件域。它指示指令在什么条件下执行。当<cond>忽略时,指令为无条件执行(cond=AL(Alway))。
         
        ② <immed_24>
        指定一个24位立即数。ARM处理器不对该立即数进行任何处理,其作用是提供给操作系统,从而判断用户程序请求的服务类型。
         
        3.指令操作的伪代码

        指令操作的伪代码如下面程序段所示。
         
        If  ConditionPassed{cond}  then
             R14_svc = address of next instruction after the SWI instruction
             SPSR_svc = CPSR
             CPSR[4:0] = 0b10011    /*进入超级用户模式*/
             CPSR[5] = 0    /*执行在ARM状态*/
             CPSR[7] = 1
             If  high  vectors configured then
                  PC = 0xffff0008
             Else
                  PC = 0x00000000
         
        4.指令举例

        (1)下面指令产生软中断,中断立即数为0。
         
        SWI   0;
         
        (2)产生软中断,中断立即数为0x123456。
         
        SWI   0x123456;
         
        (3)使用SWI指令时,通常使用以下两种方法进行参数传递。
        ① 指令24位的立即数指定了用户请求的类型,中断服务程序的参数通过寄存器传递。
        下面的程序产生一个中断号为12的软中断。
         
        MOV   r0,#34              ;设置功能号为34
        SWI   12                  ;产生软中断,中断号为12
         
        ② 另一种情况,指令中的24位立即数被忽略,用户请求的服务类型由寄存器r0的值决定,参数通过其他寄存器传递。
        下面的例子通过r0传递中断号,r1传递中断的子功能号。
         
        MOV   r0,#12                ;设置12号软中断
        MOV   r1,#34                ;设置子功能号为34
        SWI    0                       ;
         
        (4)在SWI异常中断处理程序中,取出SWI立即数的步骤为:首先确定引起软中断的SWI指令是ARM指令还是Thumb指令,这可通过对SPSR访问得到;然后要确定该SWI指令的地址,这可通过访问LR寄存器得到;然后读出指令,分解立即数。
        下面的例子为一个标准的SWI中断处理程序。
         
        T_bit      EQU      0x20
        SWI_Hander
                    STMFD     SP!,{r0_r3,r12,LR}    ;保护现场
                   MOV       r1,sp               ;设置参数指针
                    MRS       r0,SPSR             ;读取SPSR
                    STMFD     SP!,{r0,r3}          ;保持SPSR,r3压栈保证字节对齐
                    TST       r0,#T_bit            ;测试T标志位
                    LDRNEH    r0,[LR,#-2]          ;若为Thumb指令,读取指令码(16位)
                    BICNE     r0,r0,#0xff00         ;取得Thumb指令8位立即数
                    LDREQ     r0,[LR,#-4]          ;若为ARM指令,读取指令码(32位)
                    BICNQ     r0,r0,#0xff00000      ;取得ARM指令的24位立即数
                  ; r0 存储中断号
                  ; r1 指向栈顶
         
             BL      C_SWI_Handler                 ;调用主要的中断服务程序
             LDMFD   sp!, {r0, r3}                ;SPSR出栈
             MSR     spsr_cf, r0                  ;恢复SPSR
             LDMFD   sp!, {r0-r3, r12, pc}^         ;保存寄存器并返回
         
        中断服务程序的主要工作放在C_SWI_Handler中,由C语言完成,用swich_case结构判断中断类型。典型的程序如下。
         
        void C_SWI_Handler( int swi_num, int *regs )
        {
              switch( swi_num )
              {
              case    0:
                    regs[0] = regs[0] * regs[1];
              break;
         
              case    1:
                    regs[0] = regs[0] + regs[1];
              break;
         
              case    2:
                    regs[0] = (regs[0] * regs[1]) + (regs[2] * regs[3]);
              break;
         
              case    3:
              {
                    int w, x, y, z;
         
                    w = regs[0];
                    x = regs[1];
                    y = regs[2];
                    z = regs[3];
         
                    regs[0] = w + x + y + z;
                    regs[1] = w - x - y - z;
                    regs[2] = w * x * y * z;
                    regs[3] =(w + x) * (y - z);
              }
              break;
         
              }
        }
         
        9.5.2  断点中断指令BKPT

        1.指令编码格式

        断点中断指令BKPT(BreakPoint)产生一个预取异常(prefetch abort),它常被用来设置软件断点,在调试程序时十分有用。当系统中存在调试硬件时,该指令被忽略。
         
        指令的编码格式如图9.13所示。
       

        图9.13  BKPT指令编码格式

         
        2.指令的语法格式

        BKPT    <immediate>
         
        <immediate>
        16位的立即数。该立即数可以用来保存额外的断点信息。
         
                                                                         
                       
                                                                        注意
                       
                                                                        16位立即数在指令的编码格式中并不是连续存放的。前12位放在bits[19∶8],而后4位放在bits[3∶0]。
                       
         

        3.指令操作的伪代码

        指令操作的伪代码如下面程序段所示。
         
        If  (not overridden by debug hard)
               R14_abt = address of BKPT instruction + 4
               SPSR_abt = CPSR
               CPSR[4:0] = 0b10111               /*进入异常模式*/
               CPSR[5] = 0                      /*执行在ARM状态*/
               /*CPSR[6] is unchanged*/
               CPSR[7] = 1                      /*禁止正常中断*/
               If  high vectors configured then
                      PC = 0x0000000c
         
        4.指令的使用

        要正确的使用BKPT指令,必须和具体的调试系统相结合。一般说来,BKPT有两种使用方法。
         
        (1)如果当前使用的系统调试硬件没有屏蔽BKPT指令,那么在此系统中预取指令异常和软件调试命令同时使用一个中断向量。这样当异常发生时,就要依靠系统自身来判断是真正的预取异常还是软件调试命令。判断的方法,根据系统的不同,而有所不同。
         
        (2)如果当前的系统调试硬件屏蔽了BKPT指令,那么系统会跳过BKPT指令顺序执行该指令下面的程序代码。
         
                                                                         
                       
                                                                        注意
                       
                                                                        BKPT指令总是无条件执行的,当指令的编码格式中的条件域不被解析为AL时,指令的执行结果不可预知。
                       
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|文字版|手机版|DIY编程器网 ( 桂ICP备14005565号-1 )

GMT+8, 2024-11-14 15:13 , 耗时 0.091743 秒, 21 个查询请求 , Gzip 开启.

各位嘉宾言论仅代表个人观点,非属DIY编程器网立场。

桂公网安备 45031202000115号

DIY编程器群(超员):41210778 DIY编程器

DIY编程器群1(满员):3044634 DIY编程器1

diy编程器群2:551025008 diy编程器群2

QQ:28000622;Email:libyoufer@sina.com

本站由桂林市临桂区技兴电子商务经营部独家赞助。旨在技术交流,请自觉遵守国家法律法规,一旦发现将做封号删号处理。

快速回复 返回顶部 返回列表