C代码:
int cread(int *xp) {
return (xp ? *xp : 0);
}
汇编代码:(使用条件移动指令从教科书中获取编译器不允许做的示例)
movl $0, %eax
testl %edx, %edx
cmovne (%edx), %eax
这是计算机系统:程序员的角度(第2版)中使用的示例,表明如果条件的任一分支导致无法使用条件数据传输编译代码错误。在这种情况下,错误将是取消引用xp的空指针。
我知道xp被解除引用,但我不明白xp如何成为空指针。不会依赖指针作为参数传递给函数吗?
答案 0 :(得分:3)
汇编代码在技术上是有效的,但如果输入为NULL
并且因此与C代码的行为不匹配则会出错。鉴于事情的重点是在这种情况下返回零而不是错误,这是错误的。 C等价物是:
int cread(int *xp) {
int val = *xp;
return (xp ? val : 0);
}
正如您所看到的,它首先取消引用xp
,然后才检查xp
是否为NULL
,因此这显然不适用于NULL
输入。< / p>
答案 1 :(得分:2)
如果您拨打电话
cread(0);
cmovene
指令会出错,因为它会评估*xp
,即使该值永远不会被使用。
在汇编语言中,这由(%dx)
表示。即无论%dx
的值是什么,都会dx
中的地址内容。
cmov
的价值一般都受到质疑。例如,Linus Torvalds不是粉丝。