ARM内核STM32学习笔记——Thumb-2指令集与ARM指令集

摘录自 http://www.eefocus.com/book/09-08/793361276059991.html

Thumb 指令集        Thumb 指令可以看作是ARM 指令压缩形式的子集,是针对代码密度的问题而提出的,它具有16 位的代码密度。Thumb 不是一个完整的体系结构,不能指望处理只执行Thumb 指令而不支持ARM 指令集。因此,Thumb 指令只需要支持通用功能,必要时可以借助于完善的ARM 指令集,比如,所有异常自动进入ARM 状态。

        在编写Thumb 指令时,先要使用伪指令CODE16 声明,而且在ARM 指令中要使用BX指令跳转到Thumb 指令,以切换处理器状态。编写ARM 指令时,则可使用伪指令CODE32声明。

A.3.1  Thumb 指令集与ARM 指令集的区别
        Thumb 指令集没有协处理器指令,信号量指令以及访问CPSR 或SPSR 的指令,没有乘加指令及64 位乘法指令等,且指令的第二操作数受到限制;除了跳转指令B 有条件执行功能外,其它指令均为无条件执行;大多数Thumb 数据处理指令采用2 地址格式。Thumb指令集与ARM 指令的区别一般有如下几点:
         跳转指令
        程序相对转移,特别是条件跳转与ARM 代码下的跳转相比,在范围上有更多的限制,转向子程序是无条件的转移。
         数据处理指令
        数据处理指令是对通用寄存器进行操作,在大多数情况下,操作的结果须放入其中一个操作数寄存器中,而不是第3 个寄存器中。
        数据处理操作比ARM 状态的更少,访问寄存器R8~R15 受到一定限制。
        除MOV 和ADD 指令访问器R8~R15 外,其它数据处理指令总是更新CPSR 中的ALU 状态标志。
        访问寄存器R8~R15 的Thumb 数据处理指令不能更新CPSR 中的ALU 状态标志。
        单寄存器加载和存储指令
        在Thumb 状态下,单寄存器加载和存储指令只能访问寄存器R0~R7。
        批量寄存器加载和存储指令
        LDM 和STM 指令可以将任何范围为R0~R7 的寄存器子集加载或存储。
        PUSH 和POP 指令使用堆栈指令R13 作为基址实现满递减堆栈。除R0~R7 外,PUSH 指令还可以存储链接寄存器R14,并且POP 指令可以加载程序指令PC。

A.3.2  Thumb 存储器访问指令
        Thumb 指令集的LDM 和SRM 指令可以将任何范围为R0~R7 的寄存器子集加载或存储。
        批量寄存器加载和存储指令只有LDMIA、STMIA 指令,即每次传送先加载/存储数据,然后地址加4。对堆栈处理只能使用PUSH 指令及POP 指令。表A-9给出Thumb存储器访问指令。
 

表A-9  Thumb 存储器访问指令
 


        LDR 和STR
        立即数偏移的LDR 和STR 指令。存储器的地址以一个寄存器的立即数偏移指明。指令格式如下:
        LDR Rd,[Rn,#immed_5×4];加载指定地址上的数据(字),放入Rd 中
        STR Rd,[Rn,#immed_5×4];存储数据(字)到指定地址的存储单元,要存储数据在Rd 中
        LDRH Rd,[Rn,#immed_5×4];加载半字数据,放入Rd中,即Rd低16位有效,高16位清零
        STRH Rd,[Rn,#immed_5×4];存储半字数据,要存储的数据在Rd,最低16 位有效
        LDRB Rd,[Rn,#immed_5×4];加载字节数据,放入Rd中,即Rd最低字节有效,
                                                           ; 高24位清零
        STRB Rd,[Rn,#immed_5×4];存储字节数据,要存储的数据在Rd,最低字节有效
        其中:Rd 加载或存储的寄存器。必须为R0~R7。
        Rn 基址寄存器。必须为R0~R7。
        immed_5×N 偏移量。它是一个无符立即数表达式,其取值为(0~3)×N
        立即数偏移的半字和字节加载是无符号的。数据加载到Rd 的最低有效半字或字节,Rd 的其余位补0。
        地址对准一一字传送时,必须保证传送地址为32 位对准。半字传送时,必须保证传送地址为16 位对准
        立即数偏移的LDR 和STR 指令举例如下:
        LDR R0,[R1,#0x4]
        STR R3,[R4]
        LDRH R5,[R0,#0x02]
        STRH R1,[R0,#0x08]
        LDRB R3,[R6,#20]
        STRB R1,[R0,#31]
        寄存器偏移的LDR 和STR 指令。存储器的地址用一个寄存器的基于寄存器偏移来指明。指令格式如下:
        LDR Rd,[Rn,Rm] ;加载一个字数据
        STR Rd,[Rn,Rm] ;存储一个字数据
        LDRH Rd,[Rn,Rm] ;加载一个无符半字数据
        STRH Rd,[Rn,Rm] ;存储一个无符半字数据
        LDRB Rd,[Rn,Rm] ;加载一个无符字节数据
        STRB Rd,[Rn,Rm] ;存储一个无符字节数据
        LDRSH Rd,[Rn,Rm] ;加载一个有符半字数据
        LDRSB Rd,[Rn,Rm] ;存储一个有符半字数据
        其中: Rd 加载或存储的寄存器。必须为R0~R7
        Rn 基址寄存器。必须为R0~R7
        Rm 内含偏移量的寄存器。必须为R0~R7。
        寄存器偏移的半字和字节加载可以是有符号或无符号的,数据加载到Rd 的其余位拷贝符号位。
        地址对准—字传送时,必须保证传送地址为32 位对准。半字传送时,必须保证传送地址为16 位对准。
        寄存器偏移的LDR 和STR 指令举例如下:
        LDR R3,[R1,R0]
        STR R1,[R0,R2]
        LDRH R6,[R0,R1]
        STRH R0,[R4,R5]
        LDRB R2,[R5,R1]
        STRB R1,[R3,R2]
        LDRSH R7,[R6,R3]
        LDRSB R5,[R7,R2]
        PC 或SP 相对偏移的LDR 和STR 指令。用PC 或SP 寄存器中的值的立即数偏移来指明存储器的地址。指令格式如下:
        LDR Rd,[PC,#immed_8×4]
        LDR Rd,label
        LDR Rd,[SP,#immed_8×4]
        STR Rd,[SP,#immed_8×4]
        其中: Rd 加载或存储的寄存器。必须为R0~R7。
        immed_8×4] 偏移量。它是一个无符立即数表达式,其取值为(0~255)×4。
        label 程序相对偏移表达式。label 必须在当前指令之后IK 字节范围内。地址对准—地址必须是4 的整数倍。
        PC 或SP 相对偏移的LDR 和STR 指令举例如下:
        LDR R0,[PC,#0x08] ;读取PC+0x08 地址上的字数据,保存到R0 中
        LDR R7,LOCALDAT ;读取LOCALDAT 地址上的字数据,保存到R7 中
        LDR R3,[SP,#1020] ;读取SP+1020 地址上的字数据,保存到R3 中
        STR R2,[SP] ;存储R2 寄存器的数据到SP 指向的存储单元(偏移量为0)

        PUSH 和POP
        寄存器入栈及出栈指令。实现低寄存器和可选的LR 寄存器入栈寄存器和可选的PC寄存器出栈操作,堆栈地址由SP 寄存设置,堆栈是满递减堆栈。指令格式如下:
        PUSH {reglist[,LR]}
        POP {reglist[,PC]}
        其中:reglist 入栈/出栈低寄存器列表,即R0~R7。
        LR 入栈时的可选寄存器。
        PC 出栈时的可选寄存器。
        寄存器入栈及出栈指令举例如下:
        PUSH {R0-R7,LR} ;将低寄存器R0~R7 全部入栈,LR 也入栈
        POP {R0-R7,PC} ;将堆栈中的数据弹出到低寄存器R0~R7 及PC 中

         LDMIA 和STMIA
        批量加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数据。Thumb 指令集批量加载/存储指令为LDMIA 和STMIA,LDMIA 为加载多个寄存器;STM为存储多个寄存器,允许一条指令传送8 个低寄存器的任何子集。指令格式如下:
        LDMIA Rn!,reglist
        STMIA Rn!,reglist
        其中:Rn 加载/存储的起始地址寄存器。Rn 必须为R0~R7。
        Reglist 加载/存储的寄存器列表。寄存器必须为R0~R7。
        LDMIA/STMIA 的主要用途是数据复制,参数传送等,进行数据传送时,每次传送后地址加4。若Rn 在寄存器列表中,对于LDMIA 指令,Rn 的最终值是加载的值,而不是增加后的地址;对于STMIA 指令,在Rn 是寄存器列表中的最低数字的寄存器,则Rn 存储的值为Rn 在初值,其它情况不可预知。
        批量加载/存储指令举例如下:
        LDMIA R0,{R2-R7} ;加载R0 指向的地址上的多字数据,保存到R2~R7 中,
                                           ; R0 的值更新。
        STMIA R1!,{R2-R7};将R2~R7 的数据存储到R1 指向的地址上,R1 值更新。

A.3.3  Thumb 数据处理指令
        大多数Thumb 处理指令采用2 地址格式,数据处理操作比ARM 状态的更少,访问寄存器R8~R15 受到一定限制。表A-10给出Thumb数据处理指令。
 

表A-10  Thumb数据处理指令
 


        (1)数据传送指令
         MOV
        数据传送指令。将8 位立即数或寄存器(operand2)传送到目标寄存器(Rd)。指令格式如下:
        MOV Rd,#expr
        MOV Rd,Rm
        其中:Rd 目标寄存器。MOV Rd#expr 时,必须在R0~R7 之间。
        exper 8 位立即数,即0~255。
        Rm 源寄存器,为R0~R15。
        条件码标志:MOV Rd,#expr 指令会更新N 和Z 标志,对标志C 和V 无影响。而MOV,Rd,Rm 指令,若Rd 或Rm 是高寄存器(R8~R15),则标志不受影响,若Rd 或Rm 都是低寄存器(R0~R7),则会更新N 和Z,且清除标志C 和V。
        MOV 指令举例如下:
        MOV R1,#0x10 ;R1=0x10
        MOV R0,R8 ;R0=R8
        MOV PC,LR ;PC=LR,子程序返回

        MVN
        数据非传送指令。将寄存器Rm 按位取反后传送到目标寄存器(Rd)。指令格式如下:
        MVN Rd,Rm
        其中: Rd 目标寄存器。必须在R0~R7 之间。
        Rm 源寄存器。必须在R0~R7 之间。
        条件码标志:指令会更新N 和Z 标志,对标志C 和V 无影响。
        MVN 指令举例如下:
        MVN R1,R2 ;将R2 取反结果存到R1

        NEG
        数据取负指令。将寄存器Rm 乘以-1 后传送到目标寄存器(Rd)。指令格式如下:
        NEG Rd,Rm
        其中: Rd 目标寄存器,必须在R0~R7 之间。
        Rm 源寄存器。必须在R0~R7 之间。
        条件码标志:指令会更新N、Z、C、V 和标志。
        NEG 指令举例如下:
        NEG R1,R0 ;R1=-R0

        (2)算术逻辑运算指令
        ADD
        加法运算指令。将两个数据相加,结果保存到Rd 寄存器。
        低寄存器的ADD 指令的指令格式如下:
        ADD Rd,Rn,Rm
        ADD Rd,Rn,#expr3
        ADD Rd,#expr8
        其中:Rd 目标寄存器,必须在R0~R7 之间。
        Rn 第一个操作数寄存器。必须在R0~R7 之间。
        Rm 第二个操作数寄存器。必须在R0~R7 之间。
        expr3 3 位立即数,即0~7。
        expr8 8 位立即数,即0~255。
        条件码标志:指令会更新N、Z、C 和V 标志。
        高或低寄存器的ADD 指令的指令格式如下:
        ADD Rd,Rm
        其中:Rd 目标寄存器,也是第一个操数寄存器。
        Rm 第二个操作数寄存器
        条件码标志:若Rd 或Rm 都是低寄存器(R0~R7),指令会更新N、Z、C 和V 标志。其它情况不影响条件码标志。
        PC 或SP 相对偏移的ADD 指令指令格式如下:
        ADD Rd,Rp,#expr
        其中:Rd 目标寄存器,必须在R0~R7 之间。
        Rp PC 或SP,第一个操作数寄存器。
        expr 立即数,在0~1020 范围内。
        条件码标志:不影响条件码标志。
        SP 操作的ADD 指令的指令格式如下:
        ADD SP,#expr
        ADD SP,SP,#expr
        其中:SP 目标寄存器,也是第一个操作数寄存器。
        expr 立即数,在-508~+508 之间的4 的整数倍的数。
        条件码标志:不影响条件码标志。
        ADD 指令举例如下:
        ADD R1,R1,R0 ;R1=R1+R0
        ADD R1,R1,#7 ;R1=R1+7
        ADD R3,#200 ;R3=R3+200
        ADD R3,R8 ;R3=R3+R8
        ADD R1,SP,#1000 ;R1=SP+1000
        ADD SP,SP,#-500 ;SP=SP-500

        SUB
        减法运算指令。将两个数相减,结果保存到Rd 中。
        低寄存器的SUB 指令的指令格式如下:
        SUB Rd,Rn,Rm
        SUB Rd,Rn,#expr3
        SUB Rd,#expr8
        其中:Rd 目标寄存器,必须在R0~R7 之间。
        Rn 第一个操作数寄存器。必须在R0~R7 之间。
        Rm 第一个操作数寄存器。必须在R0~R7 之间。
        expr3 3 位立即数,即0~7。
        expr8 8 位立即数。即0~255。
        条件码标志:指令会更新N、Z、C 和V 标志。
        SP 操作的SUB 指令的指令格式如下:
        SUB SP,#expr
        SUB SP,SP,#expr
        其中:SP 目标寄存器,也是第一个操作数据寄存器。
        expr 立即数,在-508~+508 之间的4 的整数倍的数。
        条件码标志:不影响条件码标志。
        SUB 指令举例如下:
        SUB R0,R2,R1, ;R0=R2-R1
        SUB R2,R1,#1 ;R2=R1-1
        SUB R6,#250 ;R6=R6-250
        SUB SP,#380 ;SP=SP-380

        ADC
        带进位加法指令。将Rm 的值与Rd 的值相加,再加上CPSR 中的C 条件标志位,结果保
        存到Rd 寄存器。指令格式如下:
        ADC Rd,Rm
        其中:Rd 目标寄存器,也是第一个操作数寄存器。必须在R0~R7 之间。
        Rm 第二个操作数寄存器。必须在R0~R7 之间。
        条件码标志:指令会更新N、Z、C 和V 标志。
        ADC 指令举例如下:
        ADD R0,R0,R2,
        ADC R1,R1,R3 ;使用ADC 实现64 位加法,(R1,R0)+(R3,R2)

         SBC
        带进位减法指令。用寄存器Rd 减去Rm,再减去CPSR 中的C 条件标志的非(即若C 标志清零,则结果减去1),结果保存到Rd 中。指令格式如下:
        SBC Rd,Rm
        其中:Rd 目标寄存器,也是第一个操作数寄存器。必须在R0~R7 之间。
        Rm 第二个操作数寄存器。必须在R0~R7 之间。
        条件码标志:指令会更新N、Z、C 和V 标志。
        SBC 指令举例如下:
        SUB R0,R0,R2
        SUB R1,R1,R3 ;使用SBC 实现64 位减法,(R1,R0)=(R1,R0)-(R3,R2)

         MUL
        乘法运算指令。用寄存器Rd 乘以Rm,结果保存到Rd 中。指令格式如下:
        MUL Rd,Rm
        其中:Rd 目标寄存器,也是第一个操作数寄存器。必须在R0~R7 之间。
        Rm 第二操作数寄存器。必须在R0~R7 之间。
        条件码标志:指令会更新N 和Z 标志。
        MUL 指令举例如下:
        MUL R2,R0,R1 ;R2=R0*R1

         AND
        逻辑与操作指令。将寄存器Rd 的值与寄存器Rm 值按位作逻辑与操作,结果保存到Rd 中。指令格式如下:
        AND Rd,Rm
        其中:Rd 目标寄存器,也是第一个操作数寄存器。必须在R0~R7 之间。
        Rm 第二个操作数寄存器。必须在R0~R7 之间。
        条件码标志:指令会更新N 和Z 标志
        AND 指令举例如下:
        MOV R1,#0x0F
        AND R0,R1 ;R0=R0 & R1

         ORR
        逻辑或操作指令。将寄存器Rd 与寄存器Rn 的值按位作逻辑或操作,结果保存到Rd中。指令格式如下:
        ORR Rd,Rm
        其中:Rd 目标寄存器,也是第一个操作数寄存器。必须在R0~R7 之间。
        Rm 第二个操作数寄存器。必须在R0~R7 之间。
        条件码标志:指令会更新N 和Z 标志
        ORR 指令举例如下:
        MOV R1,#0x03
        ORR R0,R1 ;R0=R0|R1

        EOR
        逻辑异或操作指令。寄存器Rd 的值与寄存器Rn 的值按位作逻辑异或操作,结果保存到Rd 中,指令格式如下:
        EOR Rd,Rm
        其中:Rd 目标寄存器,也是第一个操作数寄存器。必须在R0~R7 之间。
        Rm 第二个操作数寄存器。必须在R0~R7 之间。
        条件码标志:指令会更新N 和Z 标志
        EOR 指令举例如下:
        MOV R2,#0Xf0
        EOR R3,R2  ;R3=R3^R2

         BIC
        位清除指令。将寄存器Rd 的值与寄存器Rm 的值反码按位作逻辑与操作。结果保存到Rd 中,指令格式如下:
        BIC Rd,Rm
        其中:Rd 目标寄存器,也是第一个操作数寄存器。必须在R0~R7 之间。
        Rm 第二个操作数寄存器。必须在R0~R7 之间。
        条件码标志:指令会更新N 和Z 标志。
        BIC 指令举例如下:
        MOV R1,#0x80
        BIC R3,R1 ;将R1 的最高位清零,其它位不变

        ASR
        算术右移指令。数据算术右移,将符号位拷贝到空位,移位结果保存到Rd 中,指令格式如下:
        ASR Rd,Rs
        ASR Rd,Rm,#expr
        其中:Rd 目标寄存器,也是第一个操作数寄存器。必须在R0~R7 之间。
        Rs 寄存器控制移位中包含移位量的寄存器。必须在R0~R7 之间。
        Rm 立即数移位的源寄存器。必须在R0~R7 之间。
        expr 立即数移位量,值为1~32
        条件码标志:指令会更新N、Z 和C 标志(若移位量为零,则不影响C 标志)。
        ASR 指令举例如下:
        ASR R1,R2
        ASR R3,R1,#2
        若移位量为32,则Rd 清零,最后移出的位保留在标志C 中,若移位量大于32,则Rd和标志C 均被清零;若移位量为0,则不影响C 标志

        LSL
        逻辑左移指令。数据逻辑左移,空位清零,移位结果保存到Rd 中,指令格式如下:
        LSL Rd,Rs
        LSL Rd,Rm,#expr
        其中:Rd 目标寄存器,也是第一个操作数寄存器。必须在R0~R7 之间。
        Rs 寄存器控制移位中包含位量的寄存器。必须在R0~R7 之间。
        Rm 立即数移位的源寄存器。必须在R0~R7 之间。
        expr 立即数移位量,值为1~31
        条件码标志:指令会更新N、Z 和C 标志(若移位量为零,则不影响C 标志)。
        LSL 指令举例如下:
        LSL R6,R7
        LSL R1,R6,#2
        若移位量为32,则Rd 清零,最后移出的位保留在标志C 中;若移位量大于32,则Rd和标志C 均被清零;若移位量为0,则不影响C 标志

        LSR
        逻辑左移指令。数据逻辑左移,空位清零,移位结果保存到Rd 中。指令格式如下:
        LSR Rd,Rs
        LSR Rd,Rm,#expr
        其中:Rd 目标寄存器,也是第一个操作数寄存器。必须在R0~R7 之间。
        Rs 寄存器控制移位中包含移位量的寄存器。必须在R0~R7 之间。
        Rm 立即数移位的源寄存器。必须在R0~R7 之间。
        expr 立即数移位量,值为1~32。
        条件码标志:指令会更新N、Z 和C 标志(若移位量为零,则不影响C 标志)。
        LSR 指令举例如下:
        LSR R3,R0
        LSR R5,R2,#2
        若移位量为32,则Rd 清零,最后移出的位保留在标志C 中;若移位量大于32,则Rd和标志C 均被清零,若移位量为0,则不影响C 标志。

         ROR
        循环右移指令。数据循环右移,寄存器右边移出的位循环移回到左边,移位结果保存到Rd 中,指令格式如下:
        ROR Rd,Rs
        其中:Rd 目标寄存器。也是第一个操作数寄存器。必须在R0~R7 之间。
        Rs 寄存器控制移位中包含移位量的寄存器。必须在R0~R7 之间。
        条件标志:指令会更新N,Z、C 的标志(若移位量为零,则不影响C 标志)。
        ROR 指令举例如下:
        ROR R2,R3

        (3)比较指令
         CMP
        比较指令。指令使用寄存器Rn 的值减去第二个操作数的值,根据操作的结果更新CPSR 中的相应条件标志位。指令格式如下:
        CMP Rn,Rm
        CMP Rn,#expr
        其中:Rn 第一个操作数寄存器。对CMP,Rn#expr 指令,Rn 在R0~R7 之间。对于CMP,Rn,Rm 指令在Rn 在R0~R15 之间。
        Rm 第二个操作数寄存器。Rm 在R0~R15 之间。
        expr 立即数,值为0~255
        条件码标志:指令会更新N、Z、C 和V 标志。
        CMP 指令举例如下:
        CMP R1,#10 ;R1 与10 比较,设置相关标志位
        CMP R1,R2 ;R1 与R2 比较,设置相关标志位

        CMN
        负数比较指令。指令使用寄存器Rn 的值加上寄存器Rm 的值,根据操作的结果更新CPSR 中的相应条件标志。指令格式如下:
        CMN Rn,Rm
        其中:Rn 第一个操作数寄存器,必须在R0~R7 之间。
        Rm 第二个操作数寄存器。必须在R0~R7 之间。
        条件码标志:指令会更新N、Z、C 和V 标志。
        CMN 指令举例如下:
        CMM R0,R2 ;R0 与R2 进行比较

         TST
        位测试指令。指令将寄存器Rn 的值与寄存器Rm 的值按位作逻辑与操作。根据操作的结果更新CPSR 相应条件标志位。指令格式如下:
        TST Rn,Rm
        其中:Rn 第一个操作数寄存器。必须在R0~R7 之间。
        Rm 第二个操作数寄存器。必须在R0~R7 之间。
        条件码标志:指令会更新N、Z、C 和V 标志。
        TST 指令举例如下:
        MOV R0,#x01
        TST R1,R0  ;判断R1 的最低位是否为0

        (4)Thumb 跳转指令
        表A-11给出Thumb跳转指令。
 

表A-11  Thumb跳转指令
 


        B
        跳转指令。跳转到指定的地址执行程序。这是Thumb 指令集中的惟一的有条件执行指令。指令格式如下:
        B{cond} label
        跳转指令B 举例如下:
        B WAITB
        BEQ LOOP1
        若使用cond 则label 必须在当前指令的-252~+256 字节范围内;若指令是无条件的,则跳转指令label 必须在当前指令的±2K 字节范围内。

         BL
        带链接的跳转指令。指令先将下一条指令的地址拷贝到R14(即LR)链接寄存器中,然后跳转到指定地址运行程序。指令格式如下:
        BL label
        带链接的跳转指令BL 举例如下:
        BL DELAYI
        机器级转指令BL 限制在当前指令的±4Mb 的范围内。(必要时,ARM 链接器插入代码以允许更长的转移。)

        BX
        带状态切换的跳转指令。跳转到Rm 指定的地址执行程序。若Rm 的位[0]为0,则Rm的位于也必须为0,跳转时自动将CPSR 中的标志T 复位,即把目标地址的代码解释为ARM代码。指令格式如下:
        BX Rm
        带状态切换的跳转指令BX 举例如下:
        ADR R0, ArmFun
        BX R0 ;跳转到R0 指定的地址,并根据R0 的最低位来切换处理器状态。

        (5)Thumb 杂项指令
        SWI
        软中断指令。SWI 指令用于产生软中断,从而实现在用户模式变换到管理模式。CPSR保存到管理模式的SPSR 中,执行转移到SWI 向量。在其它模式下也可使用SWI 指令,处理器同样地切换到管理模式。
        指令格式如下:
        SWI immed_8
        其中:immed_8 8 位立即数,值为0~255 之间的整数。
        SWI 指令举例如下:
        SWI 1 ;软中断,中断立即数为0
        SWI 0x55 ;软中断,中断立即数为0x55
        使用SWI 指令时,通常使用以下两种方法进行传递参数,SWI 异常中断处理程序可以提供相关的服务,这两种方法均是用户软件协定。SWI 异常中断处理程序要通过读取引起软中断的SWI 指令。以取得8 位立即数。
        (A)指令中8 位的立即数指定了用户请求的服务类型,参数通过用寄存器传递。
                        MOV R0,#34 ;设置子功能号为虎作34
                        SWI 18 ;调用18 号软中断
        (B)指令中的8 位立即数被忽略,用户请求的服务类型由寄存器R0 的值决定,参数通过其它的通用寄存器传递。
                MOV R0,#18 ;调用18 号软中断
                MOV R1,#34 ;设置子功能号为34
                SWI 0

        (6)Thumb 伪指令
         ADR
        小范围的地址读取伪指令。ADR 指令将基于PC 相对偏移的地址值读取到寄存器中。ADR 伪指令格式如下:
        ADR register,expr
        其中:register 加载的目标寄存器。
        expr 地址表达式。偏移量必须是正数并小于1KB。Expr 必须局部定义,不能被导入。
        ADR 伪指令举例如下:
        ADR register, expr
        其中:register 加载的目标寄存器。
        expr 地址表达式。偏移量必须是正数并小说于1KB。Expr 必须局部定义,不能被导入。
        ADR 伪指令举例如下:
        ADR R0,TxtTab
        …
        TxtTab
        DCB ”ARM7TDMI”,0

         LDR
        大范围的地址读取伪指令。LDR 伪指令用于加载32 位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR 伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV 范围,则使用MOV 或MVN 指令代替LDR 伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR 指令从文字池读出常量。LDR 伪指令格式如下:
        LDR register,=expr/label_expr
        其中:register 加载的目标寄存器
        expr 32 位立即数。
        label_expr 基于PC 的地址表达式或外部表达式。
        LADR 伪指令举例如下:
        LDR R0,=0x12345678 ;加载32 位立即数0x12345678
        LDR R0,=DATA_BUF+60 ;加载DATA_BUF 地址+60
        …
        LTORG ;声明文字池
        …
        从PC 到文字池的偏移量必须是正数小于是1KB。
        与Thumb 指令的LDR 相比,伪指令的LDR 的参数有“=”号。

         NOP
        空操作伪指令。NOP 伪指令在汇编时将会将会被代替成ARM 中的空操作,比如可能为“MOV R8,R8”指令等。NOP 伪指令格式如下:
        NOP
        NOP可用于延进操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值