为什么这个不允许编译器执行的示例导致使用 cmov 取消引用空指针? [英] Why does this example of what compilers aren't allowed to do cause null pointer dereferencing using cmov?

查看:24
本文介绍了为什么这个不允许编译器执行的示例导致使用 cmov 取消引用空指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C 代码:

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

汇编代码:(来自编译器不允许做的教科书示例)使用条件移动指令

assembly code: (from a textbook example of what a compiler isn't allowed to do) using conditional move instruction

movl    $0, %eax
testl   %edx, %edx
cmovne  (%edx), %eax

这是Computer Systems: A Programmer's Perspective(第二版)中使用的一个示例,表明如果条件的任一分支导致错误,则无法使用条件数据传输来编译代码.在这种情况下,错误将是 xp 的空指针解引用.

This is an example used in Computer Systems: A Programmer's Perspective (2nd edition) to show that code cannot be compiled using conditional data transfer if either branch of a condition results in an error. In this case, the error would be the null pointer dereferencing of xp.

我知道 xp 被取消引用,但我不明白 xp 是如何变成空指针的.这不取决于将指针作为参数传递给函数吗?

I understand that xp is dereferenced, but I don't understand how xp becomes a null pointer. Wouldn't that depend on pointer being passed as a parameter into the function?

推荐答案

汇编代码在技术上是有效的,但如果输入是 NULL 并且因此与C 代码.鉴于事情的重点是在这种情况下返回零而不是错误,这是错误的.C 等效项是:

The assembly code is technically valid, but it would fault if the input was NULL and as such doesn't match the behavior of the C code. Given that the whole point of the thing is to return zero in that case and not fault, it's wrong. The C equivalent is:

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

如您所见,它首先取消引用 xp,然后才检查 xp 是否为 NULL 所以这显然不起作用对于 NULL 输入.

As you can see, it first dereferences xp and only then checks to see if xp is NULL so this clearly won't work for NULL input.

这篇关于为什么这个不允许编译器执行的示例导致使用 cmov 取消引用空指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆