C语言中没有main函数生成可执行程序的几种方法

1、define预处理指令
这种方式很简单,只是简单地将main字符串用宏来代替,或者使用##拼接字符串。示例程序如下:
#include <stdio.h>
#define begin main
int begin(void)
{
printf("Hello, World!\n");
return 0;
}

#include <stdio.h>
#define begin m##a##i##n
int begin(void)
{
printf("Hello, World!\n");
return 0;
}
严格来说,这种方式只算是一种技巧......
2、_start函数
_start函数是C程序的入口函数,会调用main函数。在调用main函数之前,会先执行_start函数分配必要的资源,然后再调用main函数。但是在用gcc编译程序时可以使用-nostartfiles选项来重写_start函数。示例程序如下:
#include <stdio.h>
#include <stdlib.h>
_start(void) {
printf("Hello, World!\n");
exit(0);
}
编译上面的程序的命令为:
gcc -nostartfiles _start.c -o a.out
反汇编生成的可执行程序,如下所示:
a.out: file format elf64-x86-64

Disassembly of section .plt:
0000000000400320 <puts@plt-0x10>:
400320: ff 35 ea 01 20 00 pushq 0x2001ea(%rip) # 600510 <_GLOBAL_OFFSET_TABLE_+0x8>
400326: ff 25 ec 01 20 00 jmpq *0x2001ec(%rip) # 600518 <_GLOBAL_OFFSET_TABLE_+0x10>
40032c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000400330 <puts@plt>:
400330: ff 25 ea 01 20 00 jmpq *0x2001ea(%rip) # 600520 <_GLOBAL_OFFSET_TABLE_+0x18>
400336: 68 00 00 00 00 pushq $0x0
40033b: e9 e0 ff ff ff jmpq 400320 <puts@plt-0x10>
0000000000400340 <exit@plt>:
400340: ff 25 e2 01 20 00 jmpq *0x2001e2(%rip) # 600528 <_GLOBAL_OFFSET_TABLE_+0x20>
400346: 68 01 00 00 00 pushq $0x1
40034b: e9 d0 ff ff ff jmpq 400320 <puts@plt-0x10>
Disassembly of section .text:
0000000000400350 <_start>:
400350: 55 push %rbp
400351: 48 89 e5 mov %rsp,%rbp
400354: bf 68 03 40 00 mov $0x400368,%edi
400359: e8 d2 ff ff ff callq 400330 <puts@plt>
40035e: bf 00 00 00 00 mov $0x0,%edi
400363: e8 d8 ff ff ff callq 400340 exit@plt
上面的结果是完整的反汇编结果,我们可以看到_start函数中只有我们调用printf和exit函数相关的一些指令,并且.txt段中只有_start函数,没有看到main函数。如果将源代码中的_start替换为main,重新编译程序,反汇编的结果中会看到_start函数会调用到main。
另外还有一点需要注意,因为这里重写了_start函数,所以gcc为默认的main函数准备的清理动作就没用上,所以如果退出的时候直接使用return,会导致程序崩溃。所以这里要使用exit()来退出程序。具体的原因可以参见这篇文章。
3、gcc的-e选项
示例程序如下:
#include <stdio.h>
#include <stdlib.h>
int nomain(int i, int j, int k) {
printf("Hello, World!\n");
exit(0);
}
将上面的程序保存为m.c,编译命令如下所示:
gcc -nostartfiles -e nomain m.c -o a.out
继续使用objdump反汇编生成的可执行程序,结果如下:
a.out: file format elf64-x86-64

Disassembly of section .plt:
0000000000400320 <puts@plt-0x10>:
400320: ff 35 f2 01 20 00 pushq 0x2001f2(%rip) # 600518 <_GLOBAL_OFFSET_TABLE_+0x8>
400326: ff 25 f4 01 20 00 jmpq *0x2001f4(%rip) # 600520 <_GLOBAL_OFFSET_TABLE_+0x10>
40032c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000400330 <puts@plt>:
400330: ff 25 f2 01 20 00 jmpq *0x2001f2(%rip) # 600528 <_GLOBAL_OFFSET_TABLE_+0x18>
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值