CSAPP函数cread无效实现

时间:2016-02-15 06:19:50

标签: c

我是你的伟大着作CSAPP 2e的读者。我对第3.6.6章提出了一个问题。

在本章中,作者使用了一个名为cread的函数来表明在某些情况下我们不应该使用条件移动。

函数cread()如下:

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

此功能的汇编代码为:

1 movl     $0   , %eax                     Set 0 as return value
2 testl    %edx , %edx                     Test xp
3 cmovne  (%edx), %eax                     if !0, dereference xp to get return value

作者强调,如果xp为空,则xp的取消引用无效。但正如我所看到的,第1行是xp是空指针的条件,第3行,如果xp为空,(%edx)将不会被复制到{{1}因此,这段代码避免了解除引用空指针的可能性。

此外,当我在CSAPP 3e中查看此问题时,此函数的汇编代码已更改如下:

%eax

我可以在第二个汇编代码中看到第2行中的问题,如果1 cread: 2 movq (%rdi), %rax 3 tests %rdi , %rdi 4 move $0 , %edx 5 cmove %rdx , %rax 6 ret 是空指针,那么这个取消引用是一个错误。但是,我无法弄清楚第一段汇编代码中是否存在相同的错误(实际上我认为这段代码是正确的)。

我的问题是:我的理解是否正确,或者第一段汇编代码中是否存在错误?

1 个答案:

答案 0 :(得分:1)

在第三条指令中:

cmovne  (%edx), %eax

首先得到(%edx)的值,然后分析条件,最后根据条件将(%edx)移动到%eax。 因此,即使%edx = 0,它仍将访问(%edx)的值,这将导致分段错误。