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

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

3天内不再提示

BL(B)和LDR跳转范围是如何规定的

FPGA之家 来源:FPGA之家 作者:FPGA之家 2022-07-03 10:29 次阅读

1. BL LDR指令简介

2. 分析绝对跳转过程

3. BL(B)和LDR跳转范围是如何规定的

4. BL执行过程分析

5. LDR执行过程分析

6. 总结

1. BL LDR指令简介

  LDR和BL在启动程序中,都是可以负责pc跳转的指令。

  BL是地址无关指令,即和当前的运行地址无关。链接器脚本中标明了一个运行地址,但是arm中的代码实际是从地址0开始运行的。这个时候,实际的地址和运行地址是不符的

  如果想让程序正常的运行,就得使用地址无关指令。比如在完成将程序复制到内存之前想要跳转到一个函数里,就得使用BL。因为BL跳转依靠的是相对地址和运行地址无关,所以能完成跳转。

  LDR是地址有关指令。如果这个时候使用“ldr pc,=函数名”来跳转,实际上是跳转到这个函数在链接器脚本中标明的地址上了。所以使用地址相关指令之前,要把代码复制到链接器脚本中指明的那个地址上,否则的话程序就跑飞了。复制完成之后再使用LDR跳转到内存中,使程序继续运行。

2. 分析绝对跳转过程

  我们以一个例子具体分析下绝对跳转过程。

指令编号 指令功能
指令1 顺序执行
指令2 顺序执行
指令3 相对跳转到指令5
指令4 顺序执行
指令5 顺序执行
指令6 绝对跳转到指令8
指令7 顺序执行
指令8 顺序执行

  假设程序被放在0x00000000位置开始执行,编译链接后的结果为:

指令地址 指令编号 指令功能 下条指令地址
0x00000000 顺序执行 顺序执行 当前地址+4
0x00000004 顺序执行 顺序执行 当前地址+4
0x00000008 跳转到指令5 跳转到指令5 当前地址+8
0x0000000C 顺序执行 顺序执行 当前地址+4
0x00000010 顺序执行 顺序执行 当前地址+4
0x00000014 跳转到指令8 跳转到指令8 0xC000001C
0x00000018 顺序执行 顺序执行 当前地址+4
0x0000001C 顺序执行 顺序执行 当前地址+4

9af2867a-f99d-11ec-ba43-dac502259ad0.png绝对跳转分析

  当这段程序被放在0xC000000空间(如右图)时,开始执行指令1,然后采用相对寻址的方法就可以运行到指令6,在指令6执行时也可以使用绝对寻址的方法从0xC0000014正确跳转到指令8所在的0xC00001C位置,这段代码运行正常。

  当这段代码被放在0x00000000空间(如左图)时,开始执行指令1,然后采用相对寻址的方法就可以运行到指令6,但在指令6执行时使用绝对寻址的方法从0x0000014跳转到了0xC000001C,但0xC000001C空间没有代码,这样程序就跑飞了。

  因此,当编译地址(加载地址)和运行地址相同时,绝对跳转和相对跳转都可以正确执行。比如,程序在NORFLASH存储时。

  但是,当编译地址(加载地址)和运行地址不相同时,相对跳转就会出现问题。比如,代码存储在NANDFLASH,由于NANDFLASH并不能运行代码,所以需要重定位代码到内部的SRAM

3. BL(B)和LDR跳转范围是如何规定的

  下图为B(BL)指令的格式

9b145336-f99d-11ec-ba43-dac502259ad0.pngBL指令编码格式

  BL指令的[23,0]位存放的是要跳转的相对地址,由于指令所在地址必须是4字节对齐的,因此跳转的地址最低位必然是0

  BL指令[23,0]位保存的是省略这最低2位的地址,如果补全了这2位,BL指令就可以表示26位的跳转地址。在这26位中需要使用1位表示向前跳还是向后跳,那么剩下的25位就可以表示32 MBts的范围了,225=32M因此,B(BL)指令的跳转范围为-32MBytes~+32MBytes

  下图为LDR指令的格式。

9b45f3be-f99d-11ec-ba43-dac502259ad0.pngLDR指令编码格式 9b7853fe-f99d-11ec-ba43-dac502259ad0.pngLDR指令编码格式

  图中的LDR的跳转范围计算方式和B指令的类似,其中Rn和Address_mode共同构成第二个操作数的内存地址。由Address_mode的9种格式可以知道,Address_mode表示的就是偏移地址的范围大小,为212=4K。(不理解的可以对比下ldrpc, [pc, #804]和Address_mode的九种格式,很明显可以看出Address_mode就是当前地址的偏移范围)

4. BL执行过程分析

  下图为B(BL)指令的格式。

9b145336-f99d-11ec-ba43-dac502259ad0.pngBL指令编码格式

  28~31位(cond)是条件码,就是表明这条语句里是否有大于、等于、非零等的条件判断,这4位共有16种状态,分别为:

9bca6ff4-f99d-11ec-ba43-dac502259ad0.png条件码

  我们以Uboot启动过程中的这句跳转代码分析下BL指令具体的执行过程。

#ifndefCONFIG_SKIP_LOWLEVEL_INIT
blcpu_init_crit
#endif

  上述代码对应的反汇编代码如下:

33f000ac:eb000017bl33f00110
33f00110:
33f00110:e3a00000movr0,#0;0x0
33f00114:ee070f17mcr15,0,r0,cr7,cr7,{0}

  当指令执行到33f000ac时,对应的机器码为eb000017(1110_1011_0000_0000_0000_0000_0001_0111‬),其中[31,28]高四位为条件码,1110表示无条件执行。[25,27]位保留区域,24位表示是否带有返回值,1表示带有返回值,也就是BL指令。[23,0]为指令的操作数,0000_0000_0000_0000_0001_0111。

  BL指令的跳转地址是按照如下方式计算:

  1、将指令中24位带符号的补码立即数扩展为32位(扩展其符号位)原数变成 0000_0000_0000_0000_0000_0000_0001_0111。

  2、将此数左移两位0000_0000_0000_0000_0000_0010_1000_0000 变成 0000_0000_0000_0000_0000_0000_0101_1100 = 0x0000005c

   3、将得到的值加到PC寄存器中得到目标地址,由于ARM为3级流水线,此时的 pc = 33f000ac+8 = 33F000B4,pc = 33F000B4 + 0x0000005c = 33F00110‬与图中的cpu_init_crit的地址相等。

   在算的过程中我们使用的始终是PC的值,假设程序在 0 地址处执行,那么计算方法一样,pc 的值变了,计算出来的结果也随之改变。所以 BL 的跳转时是与位置无关的

5. LDR执行过程分析

  下图为LDR指令的格式。9bee8e34-f99d-11ec-ba43-dac502259ad0.png

9c0662fc-f99d-11ec-ba43-dac502259ad0.pngLDR指令编码格式

  我们以下图中的代码作为例子分析下。

ldrpc,=call_board_init_f

  对应的反汇编代码如下:

33f000d0:e59ff324ldrpc,[pc,#804];33f003fc
33f003fc:33f000d4.word0x33f000d4
........
33f000d4:
33f000d4:e3a00000movr0,#0;0x0

   ldrpc, [pc, #804]这条指令为伪指令,编译的时候会将call_board_init_f的链接地址存入一个固定的地址(链接时确定的),对于本条指令,这个地址就是33f000d4 。

  上面的反汇编出来的 ldr pc,=call_board_init_f就变成了ldrpc, [pc, #804],由于ARM使用了流水线的原因,所以在执行 ldr pc,[ pc, #4 ]的时候 pc 不在这句代码这里了,而是跑到了 pc+8的地方,这句代码相当于 pc= *(pc+804+8)=33f000d0+32C=33f003fc ,所以会跳转到33f003fc 地址取33f000d4 ,而 33f000d4 是存在代码段中的一个常量,并不是计算出来的,不会随程序的位置而改变,所以无论代码和pc怎么变 *(pc+804) 的值时不会变的。

6. 总结

  这样,绝对跳转中的固定地址就很好理解了,要跳转地址的值在链接时就已经确定了,存在了一块内存中

相对跳转时,反汇编bl33f00110中的33f00110是根据pc计算出来的,当pc改变时,结果也会改变。所以,称为相对跳转,与当前位置无关。

原文标题:分析下BL(B)/LDR指令

文章出处:【微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

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

    关注

    31

    文章

    5343

    浏览量

    120400
  • 函数
    +关注

    关注

    3

    文章

    4332

    浏览量

    62638
  • 代码
    +关注

    关注

    30

    文章

    4789

    浏览量

    68636

原文标题:分析下BL(B)/LDR指令

文章出处:【微信号:zhuyandz,微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    【NanoPi M2试用体验】+SD卡启动BL1拷贝BL2到DDR2中运行

    */bl ddr_init/* DDR初始化 */bl main/* 跳转到C函数去执行 */ldr sp, =0x34000000/* 重新设在栈为DDR内存的最高地址 */
    发表于 06-11 17:03

    ARM汇编指令(B/BL/BX)--转载

    向后的 32MB 的地址空间的跳转,包括以下 4 条指令:(1) B 跳转指令(2) BL 带返回的跳转指令(3) BLX 带返回和状态切换
    发表于 01-26 16:26

    ARM2440的启动模式

    程序。代码Head.s.extern main.text.global _start_start: b resetreset: ldr sp,=4096 bl disable_watch_dog
    发表于 07-05 05:29

    使用bl指令设置系统时钟不能正常运行

    *1024 //设置时钟 //bl Init_system_clock //执行main bl mainhalt: b haltCLOSE_WATCHDOG_S: //关闭看门狗 ldr
    发表于 03-05 03:09

    请问ldr pc, und_addr跳转是绝对地址还是相对地址?

    位置\014_und_exception_014_004\002start.S输出的错误信息:ldr pc, und_addr这一句为什么不是ldr pc, =und_addr ,ldr pc, und_addr
    发表于 04-16 07:45

    单板汇编代码报错

    to fit: R_ARM_PC24 main原因是b跳转范围不够,但是在前一句 ldr pc, =on_sdram ,这个时候pc已经跳转
    发表于 04-24 05:48

    arm汇编跳转指令总结

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

    ARM处理器中断响应为什么非要跳转两次?

    最近看uboot源码中S3C2440的start.S,源码的开始部分就是如下的代码:.globl _start_start: b reset ldr pc
    发表于 08-15 03:47

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

    (带连接的跳转指令)能够在跳转时对当前 PC 值自动进行保存。Thumb的B系列指令跳转范围只有256字节,然而大多数情况下
    发表于 04-14 09:30

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

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

    SPC58NG84E7引导加载程序,BL不会跳转到APP并继续运行BL代码是什么问题?

    我正在研究 SPC58NG84E7 引导加载程序。我有 BL 代码(在 0xFC0000),它在启动后等待 10 秒后跳转到 APP 位置 0xFD0000 并在那里执行代码。两个代码都有优化
    发表于 12-15 07:40

    跳转指令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>指令BLX上 

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

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

    全面分析下BL(B)/LDR指令

    1. BL LDR指令简介 LDRBL在启动程序中,都是可以负责pc跳转的指令。 BL是地址无
    的头像 发表于 06-01 11:15 7469次阅读
    全面分析下<b class='flag-5'>BL</b>(<b class='flag-5'>B</b>)/<b class='flag-5'>LDR</b>指令

    ATF中bl2到bl31的跳转介绍

    bl2到bl31的跳转bl2_main函数中最终会调用smc(BL1_SMC_RUN_IMAGE,(unsigned long)next
    的头像 发表于 11-07 16:09 969次阅读