繁体   English   中英

为什么这个不允许编译器执行的示例使用cmov导致空指针取消引用?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM