#define begin main
int begin(void)
{
printf(
"Hello, World!\n");
return
;
}
#include <stdio.h>
#define begin m##a##i##n
int begin(void)
{
printf(
"Hello, World!\n");
return
;
}
严格来说,这种方式只算是一种技巧......
2、_start函数
_start函数是C程序的入口函数,会调用main函数。在调用main函数之前,会先执行_start函数分配必要的资源,然后再调用main函数。但是在用gcc编译程序时可以使用-nostartfiles选项来重写_start函数。示例程序如下:
#include <stdlib.h>
_start(void) {
printf(
"Hello, World!\n");
exit(
);
}
-nostartfiles _start.c
-o a.out
: file format elf64
-x86
-
Disassembly of section .plt
:
<puts@plt
-0x10
>
:
: ff
ea
00 pushq 0x2001ea(
%rip)
# 600510 <_GLOBAL_OFFSET_TABLE_+0x8>
: ff
ec
00 jmpq
*0x2001ec(
%rip)
# 600518 <_GLOBAL_OFFSET_TABLE_+0x10>
40032c
: 0f
1f
00 nopl 0x0(
%rax)
<puts@plt
>
:
: ff
ea
00 jmpq
*0x2001ea(
%rip)
# 600520 <_GLOBAL_OFFSET_TABLE_+0x18>
:
00 00 00 00 pushq $0x0
40033b
: e9 e0 ff ff ff jmpq
<puts@plt
-0x10
>
<
exit@plt
>
:
: ff
e2
00 jmpq
*0x2001e2(
%rip)
# 600528 <_GLOBAL_OFFSET_TABLE_+0x20>
:
00 00 00 pushq $0x1
40034b
: e9 d0 ff ff ff jmpq
<puts@plt
-0x10
>
Disassembly of section .text
:
<_start
>
:
:
push
%rbp
:
e5 mov
%rsp,
%rbp
: bf
00 mov $0x400368,
%edi
: e8 d2 ff ff ff callq
<puts@plt
>
40035e
: bf 00 00 00 00 mov $0x0,
%edi
: e8 d8 ff ff ff callq
exit@plt
#include <stdlib.h>
int nomain(int i, int j, int k) {
printf(
"Hello, World!\n");
exit(
);
}
-nostartfiles
-e nomain m.c
-o a.out
: file format elf64
-x86
-
Disassembly of section .plt
:
<puts@plt
-0x10
>
:
: ff
f2
00 pushq 0x2001f2(
%rip)
# 600518 <_GLOBAL_OFFSET_TABLE_+0x8>
: ff
f4
00 jmpq
*0x2001f4(
%rip)
# 600520 <_GLOBAL_OFFSET_TABLE_+0x10>
40032c
: 0f
1f
00 nopl 0x0(
%rax)
<puts@plt
>
:
: ff
f2
00 jmpq
*0x2001f2(
%rip)
# 600528 <_GLOBAL_OFFSET_TABLE_+0x18>
:
00 00 00 00 pushq $0x0
40033b
: e9 e0 ff ff ff jmpq
<puts@plt
-0x10
>
<
exit@plt
>
:
: ff
ea
00 jmpq
*0x2001ea(
%rip)
# 600530 <_GLOBAL_OFFSET_TABLE_+0x20>
:
00 00 00 pushq $0x1
40034b
: e9 d0 ff ff ff jmpq
<puts@plt
-0x10
>
Disassembly of section .text
:
<nomain
>
:
:
push
%rbp
:
e5 mov
%rsp,
%rbp
:
ec
sub $0x10,
%rsp
:
7d fc mov
%edi,
-0x4(
%rbp)
40035b
:
f8 mov
%esi,
-0x8(
%rbp)
40035e
:
f4 mov
%edx,
-0xc(
%rbp)
: bf
00 mov $0x400375,
%edi
: e8 c5 ff ff ff callq
<puts@plt
>
40036b
: bf 00 00 00 00 mov $0x0,
%edi
: e8 cb ff ff ff callq
<
exit@plt
>
#include <stdlib.h>
void func() {
printf(
"I am func....\n");
}
int nomain1(int i, int j, int k) {
func();
printf(
"%s: Hello, World!\n", __func__);
exit(
);
}
~]
# gcc -nostartfiles p.c
/usr
/bin
/ld
: warning
: cannot find entry symbol _start; defaulting to
在单独使用nostartfiles选项时会报警告,生成的可执行程序可以执行,但是会产生段错误,去掉对func()函数的调用就不会产生段错误了。将生成的可执行程序反汇编,和使用前面的方法生成可执行程序的反汇编结果比较,发现除了函数名不一样外,没有其他区别,不知道为什么会产生段错误。知道的麻烦告知一声,拜谢!