但是,在分析一段代码时,我遇到了一个beqz指令,假设在程序上下文中,应该先执行之后的指令是没有意义的。我必须承认我的分析可能是错误的,这并非不可能。但是,我也想清除一些疑点:
所有分支/跳转指令是否总是使用分支延迟插槽,以便紧接其后的指令应首先在逻辑上执行?如果不是,在什么情况下不会呢?
是否有某种方法可以使radare2显示逻辑执行顺序,而不是二进制编码的顺序?
编辑:具体地说,我正在处理按以下顺序进行:
beqz v0, <some address>
lb v0, 0x40(sp)
我脑海中浮现着这些指令进入管道的画面。我可以想象在解码第一条指令的同时提取第二条指令。因此,实际上应该开始执行分支延迟时隙。但是,分支指令取决于分支延迟槽中的指令所修改的同一寄存器,那么会发生什么?分支指令会使用旧的寄存器值还是lb更新的新寄存器值来评估条件?
感谢
#1 楼
在分支(或跳转)指令之后评估分支延迟槽中的指令。在分支延迟槽中执行指令不会影响分支条件的评估。我观察到分支延迟槽可用于以下用途:
基本块的最后一条指令导致分支指令
分支测试将不依赖于分支延迟槽指令的计算输出
普通可以看到无条件跳转/分支,例如
b
,jal
。 如果采用分支,则不会出现副作用。
分析表明,采用分支时,不需要任何受影响的寄存器
如果采用分支,则块的第一条指令
如果分支目标有多条路径,则该指令可能会多次出现,且路径不同分支
条件值的负载,通常用于返回值
本文详细介绍了分支延迟槽。
正如Igor所指出的那样,分支指令的“可能”版本只有在实际采用该指令的情况下,才将指令的效果保持在分支延迟槽中。
#2 楼
有一些条件分支的变体,称为“可能在条件下分支”,例如
bgezl
-分支大于或等于零的可能性beql
-可能相等地分支这些指令有一个延迟槽,但是只有在采用分支的情况下,延迟槽中的指令才会执行。如果不采用分支,则延迟槽中的指令不会执行(无效)。
NB:这些指令已在MIPS体系结构的第6版中删除。
它也添加了没有延迟插槽的分支的紧凑变体
对于您的代码片段,我强烈怀疑该分支使用了旧的寄存器值,但是您可能只能通过在实际处理器上运行它来确认它。
评论
您可能会在这里阅读Raymond Chen的MIPS系列文章,从中受益:链接第一个答案为“否”(有关详细信息,请参阅链接)。我无法回答第二个。