嵌入式系统(三):ARM 指令汇编(4)

(2)(3)中介绍了ARM处理区的存储访问指令,数据处理指令,分支指令,协处理器指令等,本文对其余的指令及注意事项做一补充

文章结构

    • (5)杂项指令
      • ① 软中断指令“SWI”
        • i.参数传递
        • ii.执行过程
      • ② 状态寄存器读指令“MRS”
      • ③ 状态寄存器写指令状态寄存器写指令“MSR”
    • (6)伪指令
      • ① ADR伪指令
      • ② 中等范围地址读取
      • ③ 大范围地址读取
      • ④ 空操作伪指令“NOP”
    • 3.地址对准
    • 4.位段操作
    • 5.地址的前缀和后缀
    • 6.指令可选后缀-S后缀
    • 7.!后缀
    • 8.B后缀和H后缀
  • 四、总结
    • 一个应用实例
  • 五、THUMB指令

(5)杂项指令

在ARM指令集中杂项指令共有3条,它们非常重要,特别是与操作系统的使用息息相关:

1.软件中断产生指令:SWI
2. 程序状态寄存器读指令:MRS
3. 程序状态寄存器写指令:MSR

① 软中断指令“SWI”

SWI指令用于产生软中断,主要用于用户程序调用操作系统的系统服务。执行该指令后,处理器将完成以下动作:

  1. 切换到管理模式(操作系统使用的保护模式)
  2. 将CPSR备份到管理模式下的SPSR寄存器-也就是保存当前工作状态
  3. 程序跳转到软件中断入口
    嵌入式系统(三):ARM 指令汇编(4)_第1张图片
    1.使用操作系统后,为了防止出错的任务影响其它任务的执行,通常将任务放在用户模式执行,以限制其权限;
    2.对于一些重要的操作,如中断的开关,必须由操作系统完成。使用软件中断指令即可完成系统功能调用;

i.参数传递

SWI有两种参数传递的方式
指令中的24位立即数指定了用户请求的服务类型,参数通过通用寄存器传递。 (最常用)

MOV    R0,#34		;设置子功能号为34 
SWI    12		;调用12号软中断 

指令中的24位立即数被忽略,用户请求的服务类型由寄存器R0的值决定,参数通过其它的通用寄存器传递。


MOV    R0,#12		;调用12号软中断 
MOV    R1,#34		;设置子功能号为34 
SWI    0 

ii.执行过程

在SWI异常中断处理程序中,取出SWI指令中立即数的步骤为:
嵌入式系统(三):ARM 指令汇编(4)_第2张图片
1、CPSR的第六位即工作状态位,如果是1就是thumb指令,0即ARM指令。此时CPSR的内容已经复制到SPSR了。

2、【LR,#-2】是寄存器间接寻址,将-2加到LR上,取[LR-2]位置的操作数。

② 状态寄存器读指令“MRS”

在ARM处理器中,只有MRS指令可以对状态寄存器CPSR和SPSR进行读操作。通过读CPSR可以了解当前处理器的工作状态。读SPSR寄存器可以了解到进入异常前的处理器状态。指令格式如下所示:
嵌入式系统(三):ARM 指令汇编(4)_第3张图片

        应用示例:
    MRS    R1,CPSR	    ; 读取CPSR状态寄存器到R1
    MRS    R2,SPSR	    ; 读取SPSR状态寄存器到R2

SPSR: 在每种异常模式下都有一个程序状态寄存器SPSR, SPSR用于保存CPSR状态,以便异常返回后恢复异常发生时的工作状态

③ 状态寄存器写指令状态寄存器写指令“MSR”

在ARM处理器中,只有MSR指令可以对状态寄存器CPSR和SPSR进行写操作。与MRS配合使用,可以实现对CPSR或SPSR寄存器的读-修改-写操作,可以切换处理器模式等操作。使用时必须**精确到域,**取相应位数的数值进行写。
嵌入式系统(三):ARM 指令汇编(4)_第4张图片
嵌入式系统(三):ARM 指令汇编(4)_第5张图片
嵌入式系统(三):ARM 指令汇编(4)_第6张图片

(6)伪指令

ARM伪指令不属于ARM指令集中的指令,是为了编程方便而定义的。伪指令可以像其它ARM指令一样使用,但在编译时这些指令将被等效的ARM指令代替
嵌入式系统(三):ARM 指令汇编(4)_第7张图片

ARM伪指令有四条:
1.小范围地址读取指令:ADR
2.中等范围地址读取指令:ADRL
3.大等范围地址读取指令:LDR
4.空操作指令:NOP

① ADR伪指令

ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令,若不能用一条指令实现,则产生错误,编译失败。
嵌入式系统(三):ARM 指令汇编(4)_第8张图片

② 中等范围地址读取

ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令(ADR只有一条)。若不能用两条指令实现,则产生错误,编译失败。
嵌入式系统(三):ARM 指令汇编(4)_第9张图片

③ 大范围地址读取

LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。
嵌入式系统(三):ARM 指令汇编(4)_第10张图片

④ 空操作伪指令“NOP”

NOP伪指令在汇编时将会被代替成ARM中的空操作,比如可能是“MOV R0,R0”指令等。NOP可用于延时操作。

1.请使用NOP伪指令、比较指令、条件跳转指令等完成一个软件延时子程序,
延时长度由R0寄存器的数值控制?
Delay
       NOP		 ;空操作
       NOP
       NOP
       SUBS    R0,R0,#1 	 ;循环次数减一
       BNE      Delay	 ;如果循环未结束,跳转Delay继续
       MOV     PC,LR	 ;子程序返回

3.地址对准

所谓对齐就是数据在存储器中存放的规则,32位系统中一般有字节对齐(8bit)、半字对齐(16bit)、字对齐(32bit)三种方式,分别对齐到连续地址、偶数地址、被4整除的地址。

ARM体系结构中有ARM指令集和Thumb指令集2种,其中ARM指令为32位指令,按照4字节对齐存储,一条指令必须从4的整数倍地址来取;Thumb指令为16位指令,按2字节对齐存储,一条指令必须从偶数地址来取。

当如果一个字访问的地址是0x0003时,此时为非地址对准,将产生数据异常。

程序中可以使用一些措施保证地址对准,最方便的方法就是使用地址对准伪指令ALIGN;除此以外,也可以填充空指令NOP,空指令NOP被编译成2字节。

Cortex-M3虽然支持非对准的地址访问,但是只对下列指令可以:LDR,LDRT,LDRH,LDRHT,LDRSH,LDRSHT,STR,STRT,STRH,STRHT;而对于其他指令仍然不支持非对准的访问。因此需要注意地址对准的应用,不可以随意使用非地址对准方法。

4.位段操作

Cortex-M3也可以实现位的操作,但并不是所有的存储区域都可以实现位操作,只有两个位操作区,也称为位域。
嵌入式系统(三):ARM 指令汇编(4)_第11张图片

5.地址的前缀和后缀

①LDR R2,[R3,#0x30]     ②LDR R2,[R3],#0x30
③LDR R2,[R3,#-0x20]    ④LDR R2,[R3],#-0x20
⑤LDR R2,[R3,#0x20+0x20/2]   ⑥LDR R2,[R3],#0x20*4-0x10

第1条语句是地址前缀,这个前缀的含义是把R3+0x30地址处的数据加载给R2,注意先把R3加0x30;第2条语句是后缀,这个后缀的含义是把R3地址处的数据加载给R2,然后计算R3=R3+0x30,注意后把R3加0x30。前缀是不改变值的(想要改变必须加感叹号),后缀的地址是寄存器指向的地址,地址传输后再修改寄存器的值。

6.指令可选后缀-S后缀

S后缀的含义是:使用S后缀时,指令执行后程序状态寄存器的条件标志位将刷新;不使用S后缀,指令执行后程序状态寄存器的条件标志位将不发生变化。

指令举例如下:
    ADD R1,R2,R3
    ; 没有使用S后缀,条件标志位不刷新
    ADDS R1,R2,R3    
    ; 使用S后缀,条件标志位刷新

有些指令不需要加S后缀,在执行时同样刷新条件标志位,如比较指令CMP、CMN、测试指令TST等。
S后缀使用目的:在需要对条件进行测试,例如:是否有溢出,是否有进位,是否大于或小于等。

7.!后缀

!后缀的含义是:在指令的地址表达式中含有!后缀时,指令执行后,基址寄存器中的地址将发生变化,变化的结果如下:

指令举例如下:
LDR R2,[R1,#02]     
;没有!后缀,结果是把R1加2作为地址指针存储的数据赋给R2,R1值不变
LDR R2,[R1,#02];!后缀,结果是把R1加2作为地址指针存储的数据赋给R2,R1加2的结果送到R1中

8.B后缀和H后缀

B后缀的含义是:指令所涉及的数据是一个8位字节,不是一个字或半字。
H后缀的含义是:指令所涉及的数据是一个16位半字,不是一个字或字节。
指令举例:

LDR  R2,[R0,#20]       ;R2<-[R0+0x20]传送一个32位字
LDRB R2,[R0,#20]       ;R2<-[R0+0x20]传送一个8位字节
LDRH R2,[R0,#20]       ;R2<-[R0+0x20]传送一个半字

四、总结

  1. ARM处理器的寻址方式
    ——共有9种寻址方式;
  2. ARM指令的特点
    ——可条件执行、可选择影响标志位、具有非常灵活的第二操作数;
  3. ARM指令的种类,它能完成哪些功能
    ——共有7类指令,可以完成存储器访问、数据运算、程序跳转、处理器控制、以及帮助编程的伪指令等。

一个应用实例

      MOV R0,#0x500   	(R0: 0x500:0000 1001 0000 0000)
      ADD R1,R0,#0x06    (R1=R0+0x06=0000 1001 0000 1100)注意0x06的表示,前导0可以省略
      AND R2, R0,#0x07   (R2=0x500&0x0007=0)
      LDR R3,=0x12345678 (R3=0x12345678)
      STR R3,[R0]        (R3的内容存储到R0所在地址,R3有多个字节,遵循小断模式,以R0指向地址为起点,低位字节排放在内存的低地址端,见下图)
      LDRB R4,[R0,#2]    (R4=[R0+2]=[0x502]=0x34)
      LDRB R5,[R0]       (R5=[R0]=0x78)

嵌入式系统(三):ARM 指令汇编(4)_第12张图片

五、THUMB指令

Thumb指令集可以看作是ARM指令压缩形式的子集,它是为减小代码量而提出的,具有16位的代码密度。Thumb指令体系不完整,只支持通用功能。必要时仍需要使用ARM指令,如进入异常时。
Thumb指令集较ARM指令集有如下限制:
只有B指令可以条件执行,其它指令都不能条件执行;
分支指令的跳转范围有更多限制;
数据处理指令的操作结果必须放入其中一个操作数寄存器中,而不是第三个寄存器;
单寄存器访问指令,只能操作R0~R7;
LDM和STM指令可以对R0~R7的任何子集进行操作;

你可能感兴趣的:(嵌入式系统)