B与BL跳转指令目标地址计算方法

1、关于B(跳转指令)与BL(带返回的跳转指令):

B指令与BL指令均能使指令跳转到目标地址,两个指令和目标地址处的指令都属于ARM指令集。二者也都可以根据CPSR中条件标志位的值和指令中的执行条件决定是否执行跳转操作。二者不同的是,B指令只会执行跳转操作;BL指令在跳转的同时还会将PC寄存器的值保存到LR寄存器中。

指令的编码格式:

指令的语法格式:B{L}{<cond>}<target_address>

其中:

●    L决定是否保存返回地址。但有L时,当前PC寄存器的值会保存到LR寄存器中;当没有L时,指令只会跳转,当前PC值不会保存到LR寄存器中;
●    <cond>为指令执行的条件码;
●    <target_address>为指令跳转的目标地址。这个目标地址的计算方法是:将指令中的24位带符号的补码立即数扩展为32位(扩展其符号位);将此32位数左移两位;将得到的值加到PC寄存器中,即得到跳转的目标地址。由这种计算方法可知,跳转的范围大致为-32M~+32M。


2、B、BL跳转目标地址计算:

汇编代码:

.text
.global _start

_start:
	/* 设置内存: sp 栈 
	 * ldr sp, =4096 nand启动 
	 * ldr sp, =0x40000000+4096 nor启动 
	 */
	ldr sp, =4096  
	
	/* 调用main */
	bl main
halt:
	b halt

C文件代码:

int main()
{
	while(1);
}

反汇编代码:

00000000 <_start>:
   0:	e3a0da01 	mov	sp, #4096	; 0x1000
   4:	eb000000 	bl	c <main>

00000008 <halt>:
   8:	eafffffe 	b	8 <halt>

0000000c <main>:
   c:	e1a0c00d 	mov	ip, sp
  10:	e92dd800 	stmdb	sp!, {fp, ip, lr, pc}
  14:	e24cb004 	sub	fp, ip, #4	; 0x4
  18:	eafffffe 	b	18 <main+0xc>

目标地址计算方法:
    1. 将指令中的24位带符号的补码立即数扩展为32位(扩展其符号位);
    2. 将此32位数左移两位;
    3. 将的到的值加到PC寄存器中,即得到跳转的目标地址。

例1-以汇编代码中第十二行代码(bl main)为例:【相对跳转】
    1. 根据反汇编代码可知bl main的机器码为0xeb000000;
    2. 将指令中24位带符号的补码:0x000000,将它扩展为32位得到:0x00000000;
    3. 将此32位数左移两位得到:0x00000000,其值就是0;
    4. PC的值是当前指令的下两条(下一条的下一条)指令的地址,加上第三步的到的0(当前指令地址为4,当前指令的下两条指令即+8,所以PC=4+8+0=c(12));由此可得bl main跳转的目标地址为c,即反汇编代码中第八行main的地址。因为ARM的流水线使得指令假设执行到A处时,PC实际的值是A+8)

例2-以汇编代码中第十四行代码(b halt)为例:【相对跳转】
    1. 根据反汇编代码可知b halt的机器码为0xeafffffe;
    2. 将指令中24位带符号的补码:0xfffffe,将它扩展为32位得到:0xfffffffe;
    3. 将此32位数左移两位的到:0xfffffff8,其值就是-8;
    4. PC的值是当前指令的下两条(下一条的下一条)指令的地址,加上第三步的到的-8(当前指令地址为8,当前指令的下两条指令即+8,所以PC=8+8+(-8)=8 );由此可得b halt跳转的目标地址为8,也就是自身当前地址(此条代码起循环作用)。

(以上部分内容摘自《ARM体系结构与编程》)

3、为什么跳转范围是-32M~+32M:

在指令的编码格式中bit[23:0]跳转的目标地址,在计算时会左移两位扩展为26位有符号数,是表示要跳转的目标地址相对于PC的偏移值,表示范围为-2^25~2^25(其中有一位为符号位),也就是只能跳到相对于当前PC值偏移-32MB~+32MB的位置去,与地址绝对位置无关。

发布了6 篇原创文章 · 获赞 10 · 访问量 1万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览