3.9.4. 汇编中用bl指令和mov pc,lr来实现子函数调用和返回

和b指令类似的,另外还有一个bl指令,语法是:

BL{cond} label

其作用是,除了b指令跳转到label之外,在跳转之前,先把下一条指令地址存到lr寄存器中,以方便跳转到那边执行完毕后,将lr再赋值给pc,以实现函数返回,继续执行下面的指令的效果。

用下面这个start.S中的例子来说明:

	bl	cpu_init_crit
......
cpu_init_crit:
......
	mov	pc, lr
        

其中,就是先调用bl掉转到对应的标号cpu_init_crit,其实就是相当于一个函数了,

然后在cpu_init_crit部分,执行完毕后,最后调用 mov pc, lr,将lr中的值,赋给pc,即实现函数的返回原先 bl cpu_init_crit下面那条代码,继续执行函数。

上面的整个过程,用C语言表示的话,就相当于

......
cpu_init_crit();
......

void cpu_init_crit(void)
{
......
}
        

而关于C语言中,函数的跳转前后所要做的事情,都是C语言编译器帮我们实现好了,会将此C语言中的函数调用,转化为对应的汇编代码的。

其中,此处所说的,函数掉转前后所要做的事情,就是:

  • 函数跳转前

    要将当前指令的下一条指令的地址,保存到lr寄存器中

  • 函数调用完毕后

    将之前保存的lr的值给pc,实现函数跳转回来。继续执行下一条指令。

而如果你本身自己写汇编语言的话,那么这些函数跳转前后要做的事情,都是你程序员自己要关心,要实现的事情。

[注意]总结汇编中的:bl + mov pc,lr

汇编中bl + mov pc,lr = C语言中的子函数调用和返回