深入理解ARM跳转指令B以及在此基础上理解arm

深入理解ARM跳转指令B以及在此基础上理解arm-linux中断向量表中的内容。Posted on

讲解ARM汇编指令的书籍中,很多在讲到B指令的时候会说这条指令时一条绝对跳转指令,这是不负责任的说法。这条指令的迷惑之处在于,B指令的汇编形式为:

b label::label:mov r1,r2mov r2,r3

从汇编指令的书写形式上,确实是一条绝对跳转指令,但是实际上汇编在将“B label”这条指令翻译为机器指令的时候,会计算label相对于当前PC的偏移,将这个偏移值放到机器码中,所以实际上,B跳转指令为相对跳转指令。用相对跳转指令就可以编写位置无关的代码。

什么是位置无关的代码,其实位置无关的意思就是说编译好的一段代码可以放到内存的任何位置运行而结果不会变。了解arm-linux内核中中断向量表建立过程的同学大概都熟悉以下的一段代码:

.globl __vectors_start__vectors_start:swi SYS_ERROR0b vector_und + stubs_offsetldr pc, .LCvswi + stubs_offsetb vector_pabt + stubs_offsetb vector_dabt + stubs_offsetb vector_addrexcptn + stubs_offsetb vector_fiq + stubs_offset.globl __vectors_end__vectors_end:

上面的代码是arm-linux中中断向量表中的内容,比如:中断发生后悔就会跳转到标红的那条指令开始去执行中断处理过程。在我们编译内核的时候,上面的代码有一个链接地址,但是大家都知道,虚拟主机,在内核中中断向量表位于0xFFFF000开始的位置,内核在early_trap_init函数中会将上面的代码“搬移”到0xFFFF000开始的位置。问题就来了,b指令是怎么找到目的地址的?

下面的图很详细的解释了这个问题:

上图下面的线显示了代码被“搬移”之前相对位置,香港虚拟主机,上面的线显示了“搬移”后代码的相对位置。假设现在发生了一个数据预取异常,PC会先跳转到t1的位置执行

这样解释之后,香港服务器租用,大家可以静下心来,看着linux中的源码(arch/arm/kernel/entry-armv.S),读读上面的英文(很简单),至于上面的计算公式,我相信一个初中能够正常毕业的人就能看懂。

“b vector_dabt + stubs_offset ”

说的比较啰嗦,希望大家能有耐心看一下。

走自己的路,让人家去说吧。

深入理解ARM跳转指令B以及在此基础上理解arm

相关文章:

你感兴趣的文章:

标签云: