c++ - C 和 C++ 调用函数时 EAX 寄存器初始化的差异

标签 c++ c assembly x86-64

当编译为 C 程序或 C++ 程序(对于 Linux x86-64)时,小程序的程序集之间存在一个奇怪的差异。

有问题的代码:

int fun();
int main(){
    return fun();
}

将其编译为 C 程序(使用 gcc -O2)会产生:

main:
    xorl    %eax, %eax
    jmp fun

但是将其编译为 C++ 程序(使用 g++ -02)会产生:

main:
    jmp _Z3funv

我觉得令人费解的是,C 版本用 0 初始化主函数的返回值(xorl %eax, %eax)。

C 语言的哪个特性导致了这种必要性?

编辑:确实,对于int fun(void);,eax寄存器没有初始化。

如果根本没有fun的原型(prototype),即:

int main(){
    return fun();
}

然后 C 编译器再次将 eax 寄存器清零。

最佳答案

在 C 语言中 int fun();可以接受任意数量的参数,因此它甚至可能是一个可变参数函数。然而,在 C++ 中,这意味着它不带参数。

x86-64 sysv abi 约定要求寄存器 AL必须包含调用可变参数函数时使用的 SSE 寄存器的数量。当然,您不传递任何参数,因此它被归零。为了方便起见,编译器决定将整个 eax 归零。 。将您的原型(prototype)声明为 int fun(void);xor将会消失。

关于c++ - C 和 C++ 调用函数时 EAX 寄存器初始化的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44657747/

相关文章:

c++ - 接口(interface)和-Wctor-dtor-privacy

c++ - 是否有可能找出泄漏的 GDI 对象

c++ - 在 OpenCV 中去除噪声以创建掩码

ubuntu - 建筑琼斯福斯 - asm/unistd.h : No such file or directory

assembly - 获取 x86 汇编语言中变量的位置

c++ - Boost ASIO socket 消耗文件描述符

php - 从 C 程序调用 PHP

c - 优化乘法和加法

c - 将已编译的库链接到更新版本的 glibc

assembly - ARM 中 LDR 指令右侧的等号 = 是什么意思?