前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >嵌入式:ARM转移指令(分支指令)

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

作者头像
timerring
发布于 2022-12-25 02:01:20
发布于 2022-12-25 02:01:20
1.4K00
代码可运行
举报
文章被收录于专栏:TechBlogTechBlog
运行总次数:0
代码可运行

文章目录

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时,为转移连接指令。

汇编格式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
B{L}{<cond>}	<target address>

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

举例:

(1)无条件转移
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
B  LABEL  ;无条件跳转
         ……
LABEL  …… 
(2)执行10次循环
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	MOV  R0,#10    ;初始化循环计数器
LOOP  ……
    SUBS  R0,R0,#1      ;计数器减1,设置条件码
    BNE  LOOP      ;如果计数器R00,重复循环 
(3)调用子程序
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
      …  …
      BL  SUB          ;转移连接到子程序SUB
      ……                 ;返回到这里
 SUB  … …             ;子程序入口
      MOV  PC,R14  ;返回

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
BL   subname

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

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

(4)子程序的嵌套调用

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 BL  SUB1          ;转移连接到子程序SUB1
         ……                 ;返回到这里
 SUB1  … …             ;子程序1入口
        STMFD  SP!,{R14}
        BL  SUB2
        LTMFD SP!,{R14}
        … …
        MOV  PC,R14  ;返回
SUB2  ……  子程序入口2     
(5)条件子程序调用
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    ……
    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指令,则不会出现这样的问题

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
;从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.

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-12-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验