0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

深度剖析ARM跳转指令

汽车电子技术 来源:宅学部落 作者:王利涛 2023-02-17 09:37 次阅读

跳转指令

顺序、选择、循环是构建程序的基本结构,任何一个逻辑复杂的程序基本上都可以由这三种程序结构组合而成。而跳转指令,则在子程序调用、选择、循环程序结构中被大量使用。程序的跳转是如何实现的呢?在了解这个机制之前,我们需要先了解一下程序计数器PC。

程序计数器PC,是CPU寄存器列表中最重要的一个寄存器。它就像一杆枪,指哪打哪:你给PC指针赋值哪个地址,CPU就会到PC指针指向的这个地址去取指令、翻译指令、执行指令。一般情况下,当你没有给PC指针赋新地址时,CPU在PC指针指向的地址取完指令后,PC计数器会自动加一,指向下一条指令,程序可以自动执行下去。当我们需要跳转时,可以直接给PC指针赋一个新地址,于是CPU就会跳转到新地址去执行了。

ARM中,常见的跳转指令有B、BL、MOV、LDR等。不同的指令,它们的使用条件、使用场合是不同的,今天就给大家总结一下它们的区别及各自使用的场合。

1B跳转指令

B指令是ARM中最基本的跳转指令,它的使用方法如下:

B label

上面语句表示跳转到label的标号处去执行。B跳转指令是ARM中最简单的指令,只是单纯的跳转,而且是相对跳转。它可以跳到以当前位置PC为基址,前后32MB的地址空间范围,所以B指令只是在临近的代码块、标号之间跳转。

B指令跳转,大多数时候是单向的,跳过去就不再返回来了。但是我们可以通过添加一些标号来实现一些控制逻辑:比如循环、选择程序结构:

;循环结构示例
LOOP
    SUB R0,R0,#1
    ...
    CMP R0,#0
    BNE LOOP
;选择结构示例
    MOV R1,#10
    MOV R2,#20
    CMP R1,R2
    BEQ HERE
    ...
    B END 
HERE
    ...
END
    ...

在上面的程序中,我们使用B跳转指令实现了选择、循环这两种基本的程序结构。B指令像ARM的其它指令一样,可以根据CPSR状态寄存器的标志位,有条件的执行。这样,可以减少指令数目、提高代码密度和运行效率。如BNE、BEQ就是当结果相等、不相等时的条件跳转。

当前程序状态寄存器:

图片

各种各样的条件码:

图片

2BL指令

BL指令跟B不同:在跳转之前,会先将当前指令的下一条指令地址保存到LR寄存器中,然后才跳转到标号执行。这样做的好处是:当我们想从标号地方返回时,可以直接将LR寄存器中的返回地址赋值给PC,程序就可以返回到原来的程序中继续执行了。

BL跳转指令一般用在子程序的调用中。无论是汇编语言子程序,还是C语言子程序,在跳转到子程序之前,都要将返回地址保存起来。当子程序执行完毕,将LR寄存器保存的返回地址,重新赋值给PC,处理器就可以返回到主程序继续执行了。

BEGIN
    MOV R0,#SRC
    MOV R1,#DST
    MOV R2,#100
    BL COPY
    NOP
    ...
 COPY
    SUB R2,R2,#1
    LDR R3,[R0],#1
    STR R3,[R1],#1
    CMP R2,#0
    BNE COPY
    MOV PC,LR

上面的汇编代码段,我们定义了一个汇编子程序COPY,实现了数据拷贝的功能。当我们使用BL指令调用这个子程序COPY时,CPU会首先将当前指令的下一条指令:NOP 的地址保存到LR寄存器中,然后才跳转到COPY子程序去执行。在COPY子程序中,处理完数据搬运后,通过

MOV PC,LR

这条语句,将保存在LR寄存器中的返回地址,重新赋值给PC,这样我们就可以返回到原来的程序中继续执行了。

在上面的汇编代码中,LR,即R14,连接寄存器,常用来存放程序的返回地址;PC,即R15,程序计数器,表示当前指令地址。LR和PC都是ARM汇编器为了方便程序员编程,预定义的一些宏。你在程序中使用这些助记符其实就是相当于操作R14和R15寄存器。除此之外,ARM中常用的助记符有:

  • FP:栈帧基址寄存器,即R12
  • SP:栈指针寄存器,即R13
  • LR:链接寄存器,即R14
  • PC:程序计数器,即R15

同样,在C语言调用子函数的过程中,在跳转子函数执行之前,CPU也会将当前指令的下一条指令地址保存到LR寄存器中,然后再跳转到子函数中执行。因为在子函数运行过程中,也有可能会用到ARM的一些寄存器,也有可能会调用其它的子函数,会覆盖掉保存在LR寄存器中的返回地址,所以,我们一般在运行子函数之前,会首先将LR寄存器压入子函数的栈帧,相当于将返回地址保存到了栈上。当子函数运行结束时,再通过出栈操作,将保存在栈中的返回地址弹出到PC指针中,这样程序就成功从子程序中返回了,直接返回到原来的函数中继续执行。

int main(void)
{
    func();
    printf("Hello!\\n");
    return 0;
} 
;对应的汇编代码
main
    BL func
    BL printf
func
    PUSH LR
    ...
    pop pc 
;func子函数返回

3MOV指令

通过上面的学习,我们可以看到,无论是B指令、还是BL指令,都是相对寻址。其本质都是以当前指令地址PC为基址,然后加上一个[0,32M]的偏移,达到修改PC的目的。

除此之外,我们也可以直接给PC指针赋值,达到跳转的目的。如上面的 func 子程序返回,就是直接通过

MOV PC,LR

这条指令,将LR寄存器中的返回地址,直接赋值给PC,直返回到原来的主函数去执行。

MOV指令主要用来在寄存器之间传输数据,或者将一个立即数传送到寄存器。但是MOV指令有一个硬伤,就是传递的立即数只能是8位数,有大小的限制。这是为什么呢?很简单,ARM是RISC架构,在一个32位的ARM中,指令通常都是32位的。而一个指令中,通常要包括操作码+操作数,如下图:

图片

一条指令,总共有32个bit空间,MOV这个操作码要占几位吧,Rd寄存器编码要占据几位吧,剩下的留给立即数的空间就不多了,所以这也就限定了MOV指令能传递的立即数的大小了。而一般的32位程序中,无论是变量还是函数,它们的地址一般都是32位的,如果使用MOV指令,将他们的地址传送到PC,使用下面的形式:

MOV PC,#0x30008000

你会发现,立即数#0X30008000这个地址就已经32位了,在加上MOV指令这个操作码,已经超过32位了,编译器是无法翻译这个指令的,所以说,当一个变量或函数地址为32位时,使用MOV指令给PC直接赋值,行不通,那怎么办呢?

4LDR伪指令

办法总是有的,比如,我们就可以通过伪指令LDR,直接将一个32位的立即数地址,传送到PC:

LDR PC,=0x30008000

LDR伪指令的功能和MOV一样,都可以将一个立即数传送到寄存器。唯一区别的就是,MOV指令只能传送8位的,而LDR可以传送一个32位的立即数或地址。

这里需要注意一下,立即数 0X30008000 的前面有一个等于号“=”,这表示前面的LDR指令是一个伪指令。除此之外,在ARM中,LDR还有另外一个意思,用来将内存中的数据加载到寄存器。我们知道,ARM是RISC架构,使用LDR/STR架构,不能直接修改内存中的数据。如果我们要修改内存中的一个变量,要首先使用LDR指令将内存中的变量加载到寄存器中,接着对寄存器进行操作,最后再使用STR指令将寄存器中的变量回写到内存中。所以,LDR可以看作是一个伪指令,也可以看做是普通的一个LDR指令,判定他们的区别就是看前面的等于号。

普通的LDR指令主要使用寄存器间接寻址,常用的使用方式如下:

LDR R0,[R1]
LDR R0,0x30008000

这里注意后面一句,是将地址0x30008000地址上的内容传动到寄存器R0,而不是直接将这个地址传送到R0,这里一定要注意其跟LDR伪指令的区别,这一点没有注意到,你在分析程序时就可能误入歧途了。

在《C语言嵌入式Linux高级编程》第二期中,我们已经探讨了CPU、指令集、伪指令的基本概念,这里就不赘述了。简单来说,伪指令并不是真正的ARM指令,并不属于ARM指令集中的标准指令。它只是编译器为了方便我们程序员开发程序,定义的一些助记符。在编译时,这些伪指令还是会使用指令集中的标准指令来实现。

比如上面的LDR伪指令,程序在编译时,看到这个伪指令,会使用ARM指令集中标准的指令实现。如果LDR伪指令中的立即数小于8位,它就会转换为MOV指令来实现:

LDR R0,=200
MOV R0,#200

如果LDR伪指令中,立即数大于8bit表示的数据范围,比如说是一个32位的立即数或地址,那就不能使用MOV指令来实现了,可以采用文字池的形式,先将这个地址常量单独存放在存储单元中,然后使用相对寻址,曲线救国,完成这个32位地址或立即数与寄存器之间的传输,这些细节在教程视频中都有讲到,就不再赘述了。

5小结

通过上面的学习,我们基本上理清了ARM系统中常见的几种跳转指令,以及它们的区别。只有彻底理解他们的底层机制及实现细节,才有可能在使用反汇编分析程序时,达到事半功倍的效果,从而大大提高我们的工作效率。否则,这些基本的细节和概念搞不清,将会永远成为你学习和工作上的障碍。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 计数器
    +关注

    关注

    32

    文章

    2283

    浏览量

    95852
  • 程序结构
    +关注

    关注

    1

    文章

    7

    浏览量

    6976
  • 程序调用
    +关注

    关注

    0

    文章

    3

    浏览量

    883
收藏 人收藏
    相关推荐
    热点推荐

    c语言深度剖析

    c语言深度剖析
    发表于 04-02 09:12

    C语言深度剖析

    C语言深度剖析
    发表于 08-25 09:08

    C语言深度剖析

    C语言深度剖析[完整版].pdfC语言深度剖析[完整版].pdf (919.58 KB )
    发表于 03-19 05:11

    arm汇编跳转指令总结

    目前所知道的跳转指令有 b,bl,bep,bne.他们共同点是都是以b开头,首先从字面上分析:b:是Branch,表示分支。bl:是Branch Link表示带连接的分支。bep:Branch
    发表于 04-26 02:39

    请问一下ARM跳转指令的范围是多少

    , ?]构造跳转指令。)B,BL指令保存的是偏移地址,这个地址的计算方法是:假设跳转指令处的地址是A,
    发表于 04-14 09:30

    请问一下ARM汇编中的B跳转指令和LDR跳转的区别在哪

    请问一下ARM汇编中的B跳转指令和LDR跳转的区别有哪些不同之处呢?
    发表于 07-21 15:57

    ARM汇编语言跳转指令的特殊用法还有吗

    关于 ARM汇编语言跳转指令的特殊用法。有如下两条跳转指令: beq lablefbeq lableb其中 lable 为某段程序的标号,b
    发表于 10-31 15:30

    arm汇编语言跳转指令有何特殊用法呢?

    关于 ARM 汇编语言跳转指令的特殊用法。有如下两条跳转指令: beq lablefbeq lableb其中 lable 为某段程序的标号,
    发表于 02-24 15:28

    arm指令集(1)

    arm指令集(1)  ARM跳转指令可以从当前指令向前或向后的32MB地址空间
    发表于 03-02 15:46 79次下载

    ARM指令集(2)

    ARM指令集(2)  1.跳转指令   在ARM中有两种方式可以实现程序的跳转:一种是刀
    发表于 03-02 15:49 68次下载

    Thumb指令集之Thumb跳转指令

    Thumb指令集中的跳转指令分以下6种类型。 ① 无条件跳转,其跳转空间为2KB。 ② 条件跳转
    发表于 10-19 10:04 1次下载
    Thumb<b class='flag-5'>指令</b>集之Thumb<b class='flag-5'>跳转</b><b class='flag-5'>指令</b>

    跳转指令B及带连接的跳转指令BLX上 

    跳转(B)和跳转连接(BL)指令是改变指令执行顺序的标准方式。ARM一般按照字地址顺序执行指令
    发表于 10-19 10:26 2次下载
    <b class='flag-5'>跳转</b><b class='flag-5'>指令</b>B及带连接的<b class='flag-5'>跳转</b><b class='flag-5'>指令</b>BLX上 

    ARM嵌入式系统的中断服务例程跳转

    在32位 ARM 系统中,一般都是在中断向量表中放置一条分支指令或PC寄存器加载指令,实现 程序跳转 到 中断服务 例程的功能。例如: IRQEntry B HandleIRQ ;
    发表于 04-10 10:11 2893次阅读

    PLC跳转/标号指令的工作原理及应用举例

    跳转/标号执行是用来跳过部分程序使其不执行必须用在同一程序块内部实现跳转跳转/标号指令有两条,分别为跳转
    的头像 发表于 10-08 09:59 6511次阅读

    西门子博途SCL的GOTO跳转指令

    跳转标签和“跳转指令必须在同一个块中。在一个块中,跳转标签的名称只能指定一次。每个跳转标签可以是多个
    发表于 07-03 14:53 9642次阅读

    硬件原理图学习笔记

    这一个星期认真学习了硬件原理图的知识,做了一些笔记,方便以后查找。硬件原理图分为三类1.管脚类(gpio)和门电路类输入输出引脚,上拉电阻,三极管与门,或门,非门上拉电阻:正向标志作用,给悬空的引脚一个确定的状态三极管:反向三极管(gpio输出高电平,NP两端导通,被控制端导通,电压为0)->NPN正向三极管(gpio输出低电平,PN两端导通,被控制端导通,

    张飞实战电子官方
    04-30 18:40
    223

    TurMass™ vs LoRa:无线通讯模块的革命性突破

    TurMass™凭借其高传输速率、强大并发能力、双向传输、超强抗干扰能力、超远传输距离、全国产技术、灵活组网方案以及便捷开发等八大优势,在无线通讯领域展现出强大的竞争力。

    道生物联
    20小时前
    364

    RZT2H CR52双核BOOT流程和例程代码分析

    RZT2H是多核处理器,启动时,需要一个“主核”先启动,然后主核根据规则,加载和启动其他内核。本文以T2H内部的CR52双核为例,说明T2H多核启动流程。

    RA生态工作室
    04-03 17:14
    2k

    干簧继电器在RF信号衰减中的应用与优势

    在电子测试领域,RF(射频)评估是不可或缺的一部分。无论是研发阶段的性能测试,还是生产环节的质量检测,RF测试设备都扮演着关键角色。然而,要实现精准的RF评估,测试设备需要一种特殊的电路——衰减电路。这些电路的作用是调整RF信号的强度,以便测试设备能够准确地评估RF组件和RF电路的各个方面。衰减器的挑战衰减器的核心功能是校准RF信号的强度。为了实现这一点,衰

    斯丹麦德电子
    04-30 11:33
    633

    ElfBoard嵌入式教育科普|ADC接口全面解析

    当代信息技术体系中,嵌入式系统接口作为数据交互的核心基础设施,构成了设备互联的神经中枢。基于标准化通信协议与接口规范的技术架构,实现了异构设备间的高效数据交换与智能化协同作业。本文选取模数转换接口ADC作为技术解析切入点,通过系统阐释其工作机理、性能特征及重要参数,为嵌入式学习者爱好者构建全维度接口技术认知框架。

    ElfBoard
    04-30 09:34
    347

    深入理解C语言:C语言循环控制

    在C语言编程中,循环结构是至关重要的,它可以让程序重复执行特定的代码块,从而提高编程效率。然而,为了避免程序进入无限循环,C语言提供了多种循环控制语句,如break、continue和goto,用于改变程序的执行流程,使代码更加灵活和可控。本文将详细介绍这些语句的作用及其应用场景,并通过示例代码进行说明。Part.1break语句C语言中break语句有两种

    合众恒跃
    04-29 18:49
    442

    第 21 届(顺德)家电电源与智能控制技术研讨会圆满落幕--其利天下斩获颇丰

    2025年4月25日,其利天下应大比特之邀出席第21届(顺德)家电电源与智能控制技术研讨会,已圆满落幕。一、演讲回顾我司研发总监冯建武先生在研讨会上发表了主题为《重新定义风扇驱动:一套算法兼容百种电机的有效磁链观测器方案》的演讲,介绍了我司研发自适应技术算法(简称),该方案搭载有效磁链观测器,适配百种电机类型,结合FOC算法可实现免调参稳定启动、低速静音控制

    其利天下技术
    04-28 19:29
    1.3k

    来自资深工程师对ELF 2开发板的产品测评

    来自资深工程师对ELF 2开发板的使用测评

    ElfBoard
    04-28 15:03
    476

    飞凌嵌入式2025嵌入式及边缘AI技术论坛圆满结束

    飞凌嵌入式「2025嵌入式及边缘AI技术论坛」在深圳深铁皇冠假日酒店盛大举行,此次活动邀请到了200余位嵌入式技术领域的技术专家、企业代表和工程师用户,共享嵌入式及边缘AI技术的盛宴!

    飞凌嵌入式
    04-28 13:57
    1.5k

    常用运放电路总结记录

    一、电压跟随器电压跟随器,电路图如下:电路分析:(本文所有的运放电路分析,V+表示运放同向输入端的电压,V-表示反向输入端的电压。)1.1电压跟随器反馈电阻需不需要?在上面的电压跟随器示例中,我画上了一个反馈电阻R99,大家在学习的运放的时候,可能很多地方也会提一下这个反馈电阻,很多地方会说可加可不加,效果一样。电阻需不需要加:但是本文这里个人建议使用电压跟

    张飞实战电子官方
    04-27 19:33
    517

    运放-运算放大器经典应用电路大全-应用电路大全-20种经典电路

    20种运放典型电路总结,电路图+公式1、运放的符号表示2、集成运算放大器的技术指标(1)开环差模电压放大倍数(开环增益)大Ao(Ad)=Vo/(V±V-)=107-1012倍;(2)共模抑制比高KCMRR=100db以上;(3)输入电阻大ri>1MW,有的可达100MW以上;(4)输出电阻小ro=几W-几十W3、集成运放分析方法(V+=V-虚短,ib-=ib

    张飞实战电子官方
    04-25 19:34
    404

    RDK X3新玩法:超沉浸下棋机器人开发日记

    一、项目介绍产品中文名:超沉浸式智能移动下棋机器人产品英文名:Hackathon-TTT产品概念:本项目研发的下棋机器人,是一款能自主移动、具备语音交互并能和玩家在真实的棋盘上进行“人机博弈”的移动下棋平台,能够带给对弈者如同真人对弈的完美沉浸式体验——棋开得胜团队。该智能下棋机器人具备3个显著优点:真实棋盘棋子对弈:通过使用真实棋子、棋盘和机械臂,给对弈者

    地瓜机器人
    04-25 18:18
    462

    芯对话 | 微处理器监控电路革新:CBM70X系列 重构系统可靠性

    总述在工业自动化、消费电子、汽车电子等领域,微处理器作为系统核心,其稳定运行依赖可靠的电源监控。据统计,65%的系统故障源于电源异常——工业控制设备因电压波动导致的停机频率每月平均达3.2次,便携式设备因电池管理不当造成的续航缩水普遍超过25%,汽车电子ECU因电源扰动引发的误判率在复杂工况下高达18%。传统监控方案的三大核心痛点极端电压适应性不足:当电压低

    芯佰微电子
    04-25 10:15
    722

    喜讯!米尔电子与安路科技达成IDH生态战略合作,共筑FPGA创新生态

    以芯为基,智创未来。近日,领先的嵌入式模组厂商-米尔电子正式与国产FPGA企业‌安路科技达成IDH生态战略合作‌。双方将围绕安路科技飞龙SALDRAGON系列高性能FPSoC,联合开发核心板、开发板及行业解决方案,助力开发者开发成功,加速工业控制、边缘智能、汽车电子等领域的创新应用落地‌。米尔电子&安路科技IDH生态合作证书‌硬核技术+生态协同‌安路科技作为

    米尔电子
    04-25 08:06
    879

    FOC控制算法详解

    一、基本概念:FOC(field-orientedcontrol)为磁场导向控制,又称为矢量控制(vectorcontrol),是一种利用变频器(VFD)控制三相电机的技术,利用调整变频器的输出频率、输出电压的大小及角度,来控制电机的输出。由于处理时会将三相输出电流及电压以矢量来表示,因此称为矢量控制。二、控制原理:FOC控制的其实是电机的电磁场方向。转子的

    张飞实战电子官方
    04-24 19:33
    918