C语言 汇编程序的主程序返回值



我有一个简单的C程序,它只返回0:

int main(void) {
return 0;
}

在gdb中翻译成汇编语言后:

0x0000000100000fa0 <+0>:    push   rbp
0x0000000100000fa1 <+1>:    mov    rbp,rsp
0x0000000100000fa4 <+4>:    xor    eax,eax
0x0000000100000fa6 <+6>:    mov    DWORD PTR [rbp-0x4],0x0
0x0000000100000fad <+13>:   pop    rbp
0x0000000100000fae <+14>:   ret
0x100000fa6有一条指令存储0 (0x0)在[rbp-0x4]

我注意到相同的函数定义为

void main(void) {
return ;
}

没有这个指令。

据我所知,负位移是在堆栈帧内部用于存储/检索例程的局部变量。这个函数没有任何。指令的目的是什么?这个0到底是什么意思?

为了编译一个程序,我使用了:

gcc main.c -o main -g -O0

我的Os是macOS Mojave 10.14.6

Stack不仅用于存储局部变量,还用于存储函数的输入和输出。这个0就是main函数的返回值。在第二种情况下,main被定义为void,因此它不返回任何东西。

另一件事是,根据ABI,返回值和函数输入可以在寄存器中传递。xor ax, ax在这里。实际上,它是将要使用的真实值,因为维护堆栈上的值只是为了支持使用堆栈跟踪进行调试,例如在内核转储之后,因为无法捕获寄存器内容。

然而,根据最新的C标准,main应该定义为以下两种之一:

int main(void);
int main(int argc, char **argv);

程序的未定义行为main被定义为void。