分支预测会破坏我的程序吗?

时间:2014-07-07 13:10:57

标签: assembly computer-architecture ia-32 branch-prediction

通过本书第3章“{3}}”,它表示像

这样的实现
testl %eax, %eax
cmovne (%eax), %edx

无效,因为如果预测失败,那么我们将有NULL解除引用。还说我们应该使用分支代码。

但是,不使用条件跳转会导致相同的结果吗?例如:

.L1:
jmp *%eax

testl %eax, %eax
jne .L1

是否有可能欺骗gcc为x86-32输出类似的内容?假设我有一个指向函数的指针数组,其中一些是有效的,有些则不是,我称每个函数都不是NULL。

1 个答案:

答案 0 :(得分:5)

没有。如果jmp指令是由于测试和跳转而证明无效的推测执行的一部分,则您应该无法检测到cmove__指令的无序操作数提取。

即使条件不满足,jmp指令也是precisely documented to cause a fault if a memory access operand would cause a fault。换句话说,这不是推测性执行。它是指令语义的一部分。 移动是有条件的,而不是获取。

*%eax指令没有记录在案。

我没有明白你的示例代码,因为内存操作%eax没有条件。如果jmp *%eax包含零,则无条件执行%eax中的提取肯定会导致错误。这是正确的行为。如果您测试testl %eax, %eax je .L1 jmp *%eax .L1: 并跳转错误引用。

*%eax

不会有问题。 {{1}}的推测执行不会导致错误,除非推测证明是有效的,即真正的控制路径。这类似于坏操作码的行为,除以零等:正常的程序语义不受推测执行的影响。

无序的提取和存储确实导致各种有趣的问题在于多处理。 This article and also its first part in the preceeding issue是对此主题的精彩讨论。