嵌入式:ARM转移指令(分支指令)

举报
timerring 发表于 2022/12/24 09:35:43 2022/12/24
【摘要】 ARM有2种方法可实现程序的转移:一种是利用传送指令直接向PC寄存器R15中写入转移的目标地址,通过改变PC的值实现程序的转移;另一种就是利用转移指令。ARM的转移指令可以从当前指令向前或向后的32MB的地址空间跳转,根据完成的功能它可以分为以下4种 :B 转移指令BL 带链接的转移指令BX 带状态切换的转移指令BLX 带链接和状态切换的转移指令 转移和转移链接指令(B,BL)转移指...

ARM有2种方法可实现程序的转移:

  • 一种是利用传送指令直接向PC寄存器R15中写入转移的目标地址,通过改变PC的值实现程序的转移;
  • 另一种就是利用转移指令。

ARM的转移指令可以从当前指令向前或向后的32MB的地址空间跳转,根据完成的功能它可以分为以下4种 :

  • B 转移指令
  • BL 带链接的转移指令
  • BX 带状态切换的转移指令
  • BLX 带链接和状态切换的转移指令

转移和转移链接指令(B,BL)

转移指令B在程序中完成简单的跳转指令,可以跳转到指令中指定的目的地址。BL指令完全象转移指令一样地执行转移,同时把转移后面紧接的一条指令的地址保存到链接寄存器LR(r14),这样可以实现子程序的返回。

二进制编码

跳转目标地址的计算方法:先对指令中定义的有符号的24位转移量用符号扩展为32位,并将该32位左移2位形成字的偏移,然后将它加到程序计数器PC中(相加前程序计数器的内容为转移指令地址加8字节)。一般情况下汇编器将会计算正确的偏移。

转移范围为±32MB。

L标志为1时,为转移连接指令。

汇编格式

B{L}{<cond>}	<target address>

L指定转移与连接属性,如果不包括L,便产生没有连接的转移。<cond>是条件执行的助记符扩展,缺省为AL,即无条件转移。<target address>一般是汇编代码中的标号,是转移到的目标地址。

举例:

(1)无条件转移

B  LABEL  ;无条件跳转
         ……
LABEL  …… 

(2)执行10次循环

	MOV  R0,#10    ;初始化循环计数器
LOOP  ……
    SUBS  R0,R0,#1      ;计数器减1,设置条件码
    BNE  LOOP      ;如果计数器R00,重复循环 

(3)调用子程序

      …  …
      BL  SUB          ;转移连接到子程序SUB
      ……                 ;返回到这里
 SUB  … …             ;子程序入口
      MOV  PC,R14  ;返回

注意:在子程序返回之前,不应再调用下一级嵌套子程序。

汇编语言子程序调用及返回

在ARM汇编语言中,子程序调用是通过BL指令来完成的。BL指令的语法格式如下:

BL   subname

其中,subname是被调用的子程序的名称。BL指令完成两个操作:将子程序的返回地址放在LR寄存器(r14)中,同时将PC寄存器值设置成目标子程序的第一条指令地址。

在返回调用子程序时,转移链接指令保存到LR寄存器(r14)中的值需要拷贝回程序寄存器PC(r15)。

(4)子程序的嵌套调用

为了实现子程序的嵌套调用,应该在调用嵌套子程序之前,先将R14内容压栈保存。如:

 BL  SUB1          ;转移连接到子程序SUB1
         ……                 ;返回到这里
 SUB1  … …             ;子程序1入口
        STMFD  SP!,{R14}
        BL  SUB2
        LTMFD SP!,{R14}
        … …
        MOV  PC,R14  ;返回
SUB2  ……  子程序入口2     

(5)条件子程序调用

    ……
    CMP R0,#5     ;如果R0<5
    BLLT  SUB1   ;然后调用SUB1
    BLGE  SUB2  ;否则调用SUB2
    ……

注意:只有SUB1不改变条件,这里才能正常运行。

当转移指令转移到32MB地址空间之外时,将产生不可预测的结果。

转移交换和转移链接交换(BX,BLX)

这些指令用于支持Thumb(16位)指令集的ARM芯片,程序可以通过这些指令完成处理器从ARM状态到Thumb状态的切换。类似的Thumb指令可以使处理器切换回32位ARM指令。

在第一种格式中,寄存器Rm的值是转移目标,Rm的第0位拷贝到CPSR中的T位,进而决定是切换到Thumb状态还是ARM状态。[31:1]位移入PC。

如果Rm[0]是1,则切换到Thumb状态,并在Rm中的地址处开始执行,但需将最低位清0,使之半字对齐。

如果Rm[0]是0,则切换到ARM状态,并在Rm中的地址处开始执行,但需将Rm[1]清0,使之半字对齐 。

ARM的状态寄存器CPSR中的状态控制位T-bit(位[5])决定了当前处理器的运行状态,因此,可以通过MSR和MRS指令来直接修改CPSR的状态位,也能够改变处理器运行状态
但由于ARM采用多级流水线的结构,这样做会造成流水线上预取指令的执行错误,而如果用BX指令,则不会出现这样的问题

下面是一段直接进行状态切换的例程。

;从ARM状态开始
       CODE32    ;表明以下是ARM指令
       ADR R0, Into_Thumb+1; 得到目标地址,末位置1; 表示转移到Thumb
       BX R0     ;转向Thumb
       ……         ;执行其它代码
       CODE16    ;表明以下是Thumb指令	
Into_Thumb :  ;Thumb代码
       ADR   R5, Back_to_ARM ;得到目标地址,末位缺省为0; 转移到ARM 
        BX     R5  ;转向ARM
        ……           ;执行其它代码
        CODE32  ;表明以下是ARM指令
Back_to_ARM:      ;ARM代码段起始地址

参考文献:

孟祥莲.嵌入式系统原理及应用教程(第2版)[M].北京:清华大学出版社,2017.

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。