main函数声明

main函数声明

 

背景:

main函数经常会声明为以下方式:

int main();
int main(int argc, char* argv[]);
int main(int argc, char* argv[], char*envp[]);

还有些会将返回类型替换为void,最常见的就是

void main();

 

一、VC如何支持这些不同的main函数声明

main函数是在__tmainCRTStartup中被调用的,__tmainCRTStartup也没有做特别处理。
不同main函数声明被支持是因为main函数是使用__cdecl调用约定的。

__cdecl调用约定由调用方负责参数的压栈和出栈。

__tmainCRTStartup实现在crtexe.c中,其调用main函数的汇编码如下:

mainret = main(argc, argv, envp);
00A4BAEF mov eax,dword ptr [envp (0A572B0h)] 
00A4BAF4 push eax 
00A4BAF5 mov ecx,dword ptr [argv (0A572B4h)] 
00A4BAFB push ecx 
00A4BAFC mov edx,dword ptr [argc (0A572ACh)] 
00A4BB02 push edx 
00A4BB03 call @ILT+1355(_main) (0A41550h) 
00A4BB08 add esp,0Ch 
00A4BB0B mov dword ptr [mainret (0A572C4h)],eax

 

__tmainCRTStartup做如下处理:

1、按从右到左的顺序将三个参数压栈
2、调用main函数
3、出栈 (简单的将栈指针移上来,上移是因为栈是向下生长的)
4、将存放在eax中的返回值赋给int型的mainret

以下声明也是合法的:

int main(int a, int b, char* c, int d, char* e);

PS:关于为什么__tmainCRTStartup调用的main原型与声明的不一致也能通过编译和链接是因为__tmainCRTStartup已经是编译过的,对于函数原型的检查是在编译期执行的,链接时只需要VC链接器能找到main函数符号即可。


二、void替换int,有什么影响

有如下main函数

void main()
{
    printf("Hello, world!\n");
}

 

其汇编代码如下:

printf("Hello, world!\n");
00A4D70E mov esi,esp 
00A4D710 push offset string "Hello, world!\n" (0A53894h) 
00A4D715 call dword ptr [__imp__printf (0A586FCh)] 
00A4D71B add esp,4 
00A4D71E cmp esi,esp 
00A4D720 call @ILT+1335(__RTC_CheckEsp) (0A4153Ch) 
}
00A4D725 xor eax,eax 
00A4D727 pop edi 
00A4D728 pop esi 
00A4D729 pop ebx 
00A4D72A add esp,0C0h 
00A4D730 cmp ebp,esp 
00A4D732 call @ILT+1335(__RTC_CheckEsp) (0A4153Ch) 
00A4D737 mov esp,ebp 
00A4D739 pop ebp 
00A4D73A ret

编译器会补上xor eax,eax ,返回值放在eax中。

也就是说void替换int后,该函数返回值就是0,不能返回其它值了。其他代码使用GetExitCodeProcess()获取该进程的退出代码时,只能得到0,不具备指示意义。

 

转载于:https://www.cnblogs.com/shokey520/p/3673880.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值