C 为什么'main'以'ret'结尾而不是'ret 4'?

C 为什么'main'以'ret'结尾而不是'ret 4'?,c,disassembly,calling-convention,C,Disassembly,Calling Convention,考虑以下空C程序(标准保证编译器执行隐式返回0): 您可以在此函数中添加任何操作argc和argv的逻辑。然而,当main完成时,它的汇编代码将只执行一个简单的ret,而不是ret4。我希望看到一个ret4,因为在我看来main是其他函数的被调用方,因此必须从堆栈中清除它的两个参数:和int以及指向char数组的指针。为什么不这样做呢?大多数编译器选择让调用者清除堆栈中的参数;这一传统可以追溯到早期的C编译器和处理大量参数。在调用站点,编译器知道它推送了多少,因此调整堆栈对它来说很简单 另外,请

考虑以下空C程序(标准保证编译器执行隐式
返回0
):


您可以在此函数中添加任何操作
argc
argv
的逻辑。然而,当
main
完成时,它的汇编代码将只执行一个简单的
ret
,而不是
ret4
。我希望看到一个
ret4
,因为在我看来
main
是其他函数的被调用方,因此必须从堆栈中清除它的两个参数:和int以及指向char数组的指针。为什么不这样做呢?

大多数编译器选择让调用者清除堆栈中的参数;这一传统可以追溯到早期的C编译器和处理大量参数。在调用站点,编译器知道它推送了多少,因此调整堆栈对它来说很简单


另外,请注意,可以使用0-3(arge)参数指定历史上的main。同样,调用者(例如_start)可以只提供3,并让实现者选择。

大多数编译器选择让调用者清除堆栈中的参数;这一传统可以追溯到早期的C编译器和处理大量参数。在调用站点,编译器知道它推送了多少,因此调整堆栈对它来说很简单


另外,请注意,可以使用0-3(arge)参数指定历史上的main。同样,调用者(例如_start)可以只提供3,并让实现者选择。

main是u cdecl-因此堆栈必须调整调用者。必须是
ret
。即使是
\uu stdcall
也将是
ret2*(sizeof(void*)
-so
ret 8
ret 16
但决不
ret 4
吹毛求疵:
argv
是指向指针的指针,而不是指向数组的指针。main是uuu cdecl-所以堆栈必须调整调用者。必须是
ret
。即使是
\uu stdcall
也将是
ret 2*(sizeof(void*)
-so
ret 8
ret 16
但决不
ret 4
挑剔:
argv
是指向指针的指针,而不是指向数组的指针。
int main(int argc, char* argv[]) {}