函数返回 0 时做什么?

逆向工程 视窗 C++
2021-06-13 16:16:22

我写了一个简单的 C++ 代码并在 VS 2013 中编译它。我试图了解返回 0 后会发生什么。

int main(){
...
    return 0;
...
}

return 0 的汇编代码,转换为 xor eax, eax

011F1B19  xor         eax,eax  
}
011F1B1B  pop         ebp  
011F1B1C  ret  

ret后跳转到011F121A

011F1203  push        dword ptr ds:[11F3034h]  
011F1209  push        dword ptr ds:[11F3030h]  
011F120F  push        dword ptr ds:[11F302Ch]  
011F1215  call        main (011F1B00h)  
011F121A  add         esp,0Ch  
011F121D  mov         dword ptr ds:[011F3024h],eax  
011F1222  cmp         dword ptr ds:[11F3028h],0
011F1229  jne         __tmainCRTStartup+144h (011F1261h)
#ifndef _CRT_APP
                exit(mainret);
011F122B  push        eax  
011F122C  call        dword ptr ds:[11F2078h]  

我有两个问题:

  1. 为什么返回转换为 xor eax, eax?

  2. 为什么函数在 011F121D 和 011F1222 和 011F122C 的 ds 段中取消引用 ptr?

2个回答
xor eax, eax

是将寄存器归零的最快方法。您将在 x86 上随处可见所有 x86 ABI 都指定在eax寄存器中放置一个整数返回值

ds是大多数内存访问的默认段。您的反汇编程序只是明确的。

我不熟悉 Windows 上的细节,但基本上编译到程序中的 C 运行时存根将从 main 获取返回值,并将其传递给系统调用以退出进程。(从返回main相当于调用exit。)

异或的原因是显而易见的。返回值。在 x86/64 中使用 c++ 时,函数的返回值在返回之前存储在 EAX 寄存器中。因为你写了“return 0”,所以 eax 的值必须是 0:

opcode: b8 00 00 00 00 asm:mov eax, 0*

优化器做出更好的选择:

opcode: 31 c0 asm: xor eax, eax

所以结果等于 eax = 0 优化。

关于“ 011F3024h ”,由于操作系统必须处理每个程序的返回值,因此必须保存您的返回地址以备后用。这就是(简单的答案)更详细的答案阅读__tmainCRTStartup的RE