【发布时间】:2015-11-27 19:18:47
【问题描述】:
C 代码:
int cread(int *xp) {
return (xp ? *xp : 0);
}
汇编代码:(来自一个教科书示例,说明编译器不允许做什么)使用条件移动指令
movl $0, %eax
testl %edx, %edx
cmovne (%edx), %eax
这是 Computer Systems: A Programmer's Perspective(第 2 版)中使用的示例,用于说明如果条件的任一分支导致错误,则无法使用条件数据传输编译代码。在这种情况下,错误将是 xp 的空指针解引用。
我知道 xp 被取消引用,但我不明白 xp 是如何变成空指针的。这不取决于将指针作为参数传递给函数吗?
【问题讨论】:
-
是的,只有
NULL作为参数传入。但代码的重点是检查NULL,在这种情况下返回零。cmov版本无法做到这一点,因为它总是会尝试取消引用指针,所以它会出错而不是返回零。 -
这个问题有些误导。我不认为显示的汇编代码实际上是由 gcc 生成的。如果是,那就是编译器错误。
-
@WumpusQ.Wumbley:你是对的。书中的汇编代码实际上将
Invalid implementation of function cread xp in register %edx作为无效示例代码的前言(OP 向我们展示的部分)。它不是由 gcc 生成的,正如这个 OP 所暗示的那样。 -
在我看来它匹配。因为
movl 0,eax而不是 xoring eax ? -
cmov[cc] (mem), %reg不是安腾式的推测性负载。 无条件地执行加载,仅预测目标寄存器的值。