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

标签 c assembly x86

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 并且因此与 C 代码的行为不匹配,它将出错。鉴于事情的重点是在那种情况下返回零而不是错误,这是错误的。 C 等价物是:

int cread(int *xp) {
    int val = *xp;
    return (xp ? val : 0);
}

如您所见,它首先取消对 xp 的引用,然后才检查 xp 是否为 NULL,因此这显然行不通对于 NULL 输入。

关于c - 为什么这个不允许编译器执行的示例会导致使用 cmov 取消引用空指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33963627/

相关文章:

c - 了解指针和结构体的关系

c - Travis 上的 MIPS 交叉编译

macos - 如何使用 printf 为 64 位 Mac OS X 编写汇编语言 hello world 程序?

c - 在 64 位 x86 平台上比较 PIE、PIC 代码和可执行文件有什么区别?

assembly - 如何增值?

读取单独的字符串时出现 C 段错误

c - getopt 不适用于一个参数

assembly - 如何检查有符号整数是 neg 还是 pos?

linux - 如何修复 'SYSCALL execve' : ls complains about a NULL argv[0]

x86调用栈保存一个字节