[英]Why does this example of what compilers aren't allowed to do cause null pointer dereferencing using cmov?
C代码:
int cread(int *xp) {
return (xp ? *xp : 0);
}
汇编代码:(使用教科书中不允许进行编译的示例)使用条件移动指令
movl $0, %eax
testl %edx, %edx
cmovne (%edx), %eax
这是“ 计算机系统:程序员的观点” (第2版)中使用的一个示例,该示例显示如果条件的任一分支导致错误,则无法使用条件数据传输来编译代码。 在这种情况下,错误将是xp的空指针取消引用。
我了解xp已被取消引用,但我不了解xp如何成为空指针。 那不取决于将指针作为参数传递给函数吗?
汇编代码在技术上是有效的,但是如果输入为NULL
并因此与C代码的行为不匹配,则会出错。 考虑到事情的全部目的是在那种情况下返回零而不是错误,这是错误的。 C等效项是:
int cread(int *xp) {
int val = *xp;
return (xp ? val : 0);
}
如您所见,它首先取消对xp
引用,然后才检查xp
是否为NULL
因此,这显然不适用于NULL
输入。
如果您拨打电话
cread(0);
cmovene
指令将cmovene
段错误,因为即使永远不会使用该值,它也会计算*xp
。
在汇编语言中,这由(%dx)
。 即,无论dx
的值如何,都采用%dx
中地址的内容。
人们普遍质疑cmov
的价值。 例如Linus Torvalds不是粉丝。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.