我正在静态撤消使用radare2为Atheros AR7161编译的某些软件。该处理器实现了MIPS,我确实记得MIPS具有分支延迟槽。这确实在反汇编中是很明显的,因为我可以看到应该在将分支放在其后的逻辑上执行的指令。

但是,在分析一段代码时,我遇到了一个beqz指令,假设在程序上下文中,应该先执行之后的指令是没有意义的。我必须承认我的分析可能是错误的,这并非不可能。但是,我也想清除一些疑点:


所有分支/跳转指令是否总是使用分支延迟插槽,以便紧接其后的指令应首先在逻辑上执行?如果不是,在什么情况下不会呢?
是否有某种方法可以使radare2显示逻辑执行顺序,而不是二进制编码的顺序?

编辑:具体地说,我正在处理按以下顺序进行:

beqz v0, <some address>
lb v0, 0x40(sp)


我脑海中浮现着这些指令进入管道的画面。我可以想象在解码第一条指令的同时提取第二条指令。因此,实际上应该开始执行分支延迟时隙。但是,分支指令取决于分支延迟槽中的指令所修改的同一寄存器,那么会发生什么?分支指令会使用旧的寄存器值还是lb更新的新寄存器值来评估条件?

感谢

评论

您可能会在这里阅读Raymond Chen的MIPS系列文章,从中受益:链接第一个答案为“否”(有关详细信息,请参阅链接)。我无法回答第二个。

#1 楼

在分支(或跳转)指令之后评估分支延迟槽中的指令。在分支延迟槽中执行指令不会影响分支条件的评估。

我观察到分支延迟槽可用于以下用途:


基本块的最后一条指令导致分支指令


分支测试将不依赖于分支延迟槽指令的计算输出
普通可以看到无条件跳转/分支,例如bjal


如果采用分支,则不会出现副作用。
分析表明,采用分支时,不需要任何受影响的寄存器


如果采用分支,则块的第一条指令


如果分支目标有多条路径,则该指令可能会多次出现,且路径不同分支


条件值的负载,通常用于返回值

本文详细介绍了分支延迟槽。

正如Igor所指出的那样,分支指令的“可能”版本只有在实际采用该指令的情况下,才将指令的效果保持在分支延迟槽中。

#2 楼


有一些条件分支的变体,称为“可能在条件下分支”,例如



bgezl-分支大于或等于零的可能性

beql-可能相等地分支



这些指令有一个延迟槽,但是只有在采用分支的情况下,延迟槽中的指令才会执行。如果不采用分支,则延迟槽中的指令不会执行(无效)。

NB:这些指令已在MIPS体系结构的第6版中删除。
它也添加了没有延迟插槽的分支的紧凑变体

对于您的代码片段,我强烈怀疑该分支使用了旧的寄存器值,但是您可能只能通过在实际处理器上运行它来确认它。