Ldr和bl在启动程序中,都是可以负责pc跳转的指令。
1)bl是地址无关指令,和什么地址无关呢?和当前的运行地址无关,链接器脚本中标明了一个运行地址,但是arm中的代码实际是从地址0开始运行的。这个时候实际的地址和运行地址是不符的,如果想让程序正常的运行,就得使用地址无关指令。比如在完成将程序复制到内存之前想要跳转到一个函数里,就得使用bl,因为bl跳转依靠的是相对地址,和运行地址无关,所以能完成跳转。
2)Ldr是地址有关指令,如果这个时候使用“ldr pc,=函数名”来跳转,实际上是跳转到这个函数在链接器脚本中标明的地址上了。所以使用地址相关指令之前,要把代码复制到链接器脚本中指明的那个地址上,否则的话程序就跑飞了。复制完成之后再使用ldr跳转到内存中,使程序继续运行。
注意:按lds文件连接的不同模块,不能用bl实现跳转,如下:
SECTIONS {
firtst 0x00000000 : { crt0.o }
second 0x00000000 : AT(0x0100) { leds.o }
}
是不能使用bl从crt0中跳转到,但可以使用ldr,可以改成如下就可以使用bl了:
SECTIONS {
firtst 0x00000000 : { crt0.o leds.o }
}