为什么条件移动不能正常工作

时间:2013-06-26 03:03:07

标签: assembly

在编译下面的代码后,该功能似乎没有按预期工作。

int cread(int *xp){

     return (xp?*xp:0);

}

我在汇编版本中提取对应物,如下所示。

注册xp

中的

%edx

movl $0, %eax
testl  %edx, %edx
cmovne (%edx), %eax

有人能告诉我为什么即使测试失败,指针xp仍被cmovne取消引用? ZF 1 testl时,%edx的{​​{1}}设置不是0

1 个答案:

答案 0 :(得分:3)

英特尔指令集手册似乎表明如果不满足条件,则不会读取CMOV操作数。 (我怀疑手册中给出的指令的“算法”并不完全正确。)

显然,其他人不同意;看到明确的警告here

如果源操作数是内存操作数,则无论是否满足条件,都始终读取它。这意味着无论从内存读取生成什么异常,都会生成。如果读取的内存会导致#GP或#PG,那么就这样吧。

我怀疑其原因是:指令解码器在指令完全解码并准备好执行之前,尽可能早地读取指令,计算有效地址并发出存储器读取。因此,对内存的读取会提前调度/执行并导致陷阱。直到执行单元实际到达CMOV它才知道不需要存储器读取,并且延迟启动它会使指令真正变慢,并使指令预取逻辑复杂化。

我只使用它的寄存器寄存器形式,它不会陷阱。