从学习arm汇编开始就一直以为arm的指令b是一个绝对跳转指令,最近在学习u-boot,看到一处使用b的例子,觉得这个指令并不是直接跳转那么回事。 写了个测试的例子: head.s ==================== .global _start .text _start: b reset b aa b bb b 0x30 reset: .space 8,0xab aa: .word 0xdeadbeef .space 8,0xab bb: .word 0xdeadbeef .word 0xdeadbeef .end ==================== 执行命令:arm-none-eabi-gcc -mcpu=arm7tdmi -c head.s -o head.o&&arm-none-eabi-gcc -Ttext 0x0 -mcpu=arm7tdmi -nostartfiles head.o -o head.elf&&arm-none-eabi-objdump -d head.elf 后的输出结果如下(反汇编): ================== Disassembly of section .text: 00000000 <_start>: 0: ea000002 b 10 <reset> 4: ea000003 b 18 <aa> 8: ea000005 b 24 <bb> c: ea000004 b 24 <bb> 00000010 <reset>: 10: abababab .word 0xabababab 14: abababab .word 0xabababab 00000018 <aa>: 18: deadbeef .word 0xdeadbeef 1c: abababab .word 0xabababab 20: abababab .word 0xabababab 00000024 <bb>: 24: deadbeef .word 0xdeadbeef 28: deadbeef .word 0xdeadbeef
================== 从上面的例子可以看到: b reset==>ea000002 b aa==>ea000003 b bb==>ea000005 b 0x30==>ea000004 从上面可以发现规律:指令所要跳转到的标号地址=执行这条指令时PC的值(这条指令的地址值+8,预取指的原因)+机器码中的立即数*4 比如,<reset>=0+8+2*4=0x10 <aa>=4+8+3*4=0x18 也就是标号处是当前指令的地址向后数(机器码中的立即数+2)个指令,也就是它跳转时是相对PC当前值的。 至于直接跳转到数字值(上面的b 0x30)怎么生成的地址,还没搞清楚。。。 至少,从这个例子可以看出,b指令也是相对跳转指令,它所要跳到的标号跟当前指令的地址有关。 (这个是自己的理解,欢迎大牛批评指正!) |