当前位置: 首页 > 科技观察

我们来分析一下BL(B)-LDR指令

时间:2023-03-23 10:34:55 科技观察

1。BLLDR指令介绍2.绝对跳跃过程分析3.如何指定BL(B)和LDR跳跃范围4。BL执行过程分析5.LDR执行过程分析六、总结1、BLLDR指令介绍LDR和BL是启动程序中可以负责pc跳转的指令。BL是地址无关指令,即与当前操作地址无关。链接描述文件中标记了一个运行地址,但arm中的代码实际上是从地址0开始运行的,此时实际地址与运行地址不匹配。要想程序正常运行,就得使用地址无关指令。例如,如果要在将程序复制到内存之前跳转到某个函数,则必须使用BL。因为BL跳转依赖于相对地址,与运行地址无关,所以可以完成跳转。LDR是地址相关的指令。如果此时使用“ldrpc,=函数名”跳转,实际上是跳转到链接描述文件中这个函数指示的地址。所以在使用地址相关的指令之前,必须将代码复制到链接描述文件中指定的地址,否则程序会跑掉。拷贝完成后,使用LDR跳转到内存,让程序继续运行。2.绝对跳转过程分析下面用一个例子来分析一下绝对跳转过程。指令编号指令功能指令1顺序执行指令2顺序执行指令3相对跳转指令5指令4顺序执行指令5顺序执行指令6绝对跳转指令8指令7顺序执行指令8顺序执行假设程序放在0x00000000处position开始执行,编译链接后结果为:指令地址指令号指令功能下一条指令地址0x00000000顺序执行顺序执行当前地址+40x00000004顺序执行顺序执行当前地址+40x00000008跳转到指令5跳转到指令5当前地址+80x0000000C顺序执行顺序执行当前地址+40x00000010顺序执行顺序执行当前地址+40x00000014跳转到指令8跳转到指令80xC000001C0x00000018顺序执行顺序执行当前地址+40x0000001C顺序执行顺序执行当前地址+4绝对跳转分析当本程序放在0xC000000空间时(如右图),开始执行指令1,然后使用相对寻址方式运行到指令6。执行指令6时,也可以使用绝对寻址方式从0xC0000014正确跳转到指令8。在0xC00001C的位置,这段代码运行正常。当这段代码放到0x00000000的空间时(如左图),开始执行指令1,然后可以使用相对寻址的方式执行指令6,但是执行指令6时使用的是绝对寻址方式从0x0000014跳转到0xC000001C,但是0xC000001C空间没有代码,所以程序会跑掉。因此,当编译地址(加载地址)和运行地址相同时,绝对跳转和相对跳转都可以正确执行。例如,当程序存储在NORFLASH中时。但是,当编译地址(加载地址)和运行地址不相同时,相对跳转就会出现问题。例如,代码存储在NANDFLASH中。由于NANDFLASH无法运行代码,需要将代码重新定位到内部SRAM中。3、BL(B)和LDR的跳跃范围是如何规定的?B(BL)指令的格式如下图所示。地址必须是4字节对齐的,所以跳转地址的最低位必须为0。BL指令的[23,0]位保存的是省略最低2位的地址。如果这2位都完成了,BL指令就可以代表一个26位的跳转地址。需要用26位中的一位来表示是向前跳还是向后跳,那么剩下的25位就可以表示32MBts的范围,225=32M。因此,B(BL)指令的跳转范围为-32MBytes~+32MBytes。LDR指令的格式如下图所示。LDR指令编码格式LDR指令编码格式图中LDR的跳转范围计算方法与B指令类似,其中Rn和Address_mode共同构成第二个操作数的内存地址。从Address_mode的9种格式可以知道,Address_mode表示偏移地址的范围,即212=4K。(不明白的可以对比一下ldrpc、[pc,#804]和Address_mode这九种格式,很明显Address_mode就是当前地址的偏移范围。)四、BL执行过程分析图下面显示了B(BL)指令格式。BL指令编码格式的28~31位(cond)为条件码,表示该语句中是否存在大于、等于、非零等条件判断。这4位有16种状态,分别是:条件码。这段启动过程中的跳转代码分析了BL指令的具体执行过程。#ifndefCONFIG_SKIP_LOWLEVEL_INITblcpu_init_crit#endif上述代码对应的反汇编代码如下:33f000ac:eb000017bl33f0011033f00110:33f00110:e3a00000movr0,#0;0x033f00114: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.Movethisnumbertotwodigits0000_0000_0000_0000_0010_1000_0000to0000_0000_0000_0000_0000_00101_1100=0x0000005c3,addthevaluetothePCregistertogetthetargetaddress,becausetheARMisthelevel3streamline,atthistimethePC=33F000AC+83F000B4,PC33F000B4,PC00000B4,电脑00000B4,电脑。+0x0000005c=33F00110?等于图中cpu_init_crit的地址。4在计算的过程中,我们总是使用PC的值。假设程序在地址0处执行,那么计算方法是一样的。如果pc的值发生变化,计算的结果也会随之变化。所以BL的跳跃时间和站位无关。5、LDR执行过程分析下图为LDR指令的格式。以下图代码为例分析图像LDR指令的编码格式。ldrpc,=call_board_init_f对应的反汇编代码如下:33f000d0:e59ff324ldrpc,[pc,#804];33f003fc33f003fc:33f000d4.word0x33f000d4.......33f000d4,#33f000d4