1、define預處理指令
這種方式很簡單,只是簡單地將main字串用巨集來代替,或者使用##拼接字串。示例程式如下:
#include
#define begin main
int begin(void)
#include
#define begin m##a##i##n
int begin(void)
嚴格來說,這種方式只算是一種技巧......
2、_start函式
_start函式是c程式的入口函式,會呼叫main函式。在呼叫main函式之前,會先執行_start函式分配必要的資源,然後再呼叫main函式。但是在用gcc編譯程式時可以使用-nostartfiles選項來重寫_start函式。示例程式如下:
#include
#include
_start(void)
編譯上面的程式的命令為:
gcc -nostartfiles _start.c -o a.out
反彙編生成的可執行程式,如下所示:
a.out: file format elf64-x86-64
disassembly of section .plt:
0000000000400320 :
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 :
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
0000000000400340 :
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
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
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
#include
int nomain(int i, int j, int k)
將上面的程式儲存為m.c,編譯命令如下所示:
gcc -nostartfiles -e nomain m.c -o a.out
繼續使用objdump反彙編生成的可執行程式,結果如下:
a.out: file format elf64-x86-64
disassembly of section .plt:
0000000000400320 :
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 :
400330: ff 25 f2 01 20 00 jmpq *0x2001f2(%rip) # 600528 <_global_offset_table_+0x18>
C語言中main函式的引數
我們經常用的main函式都是不帶引數的。因此main 後的括號都是空括號。實際上,main函式可以帶引數,這個引數可以認為是 main函式的形式引數。語言規定main函式的引數只能有兩個,習慣上這兩個引數寫為argc和argv。因此,main函式的函式頭可寫為 main argc,argv 語言還規...
C語言中main函式的引數
我們經常用的main函式都是不帶引數的。因此main 後的括號都是空括號。實際上,main函式可以帶引數,這個引數可以認為是 main函式的形式引數。語言規定main函式的引數只能有兩個,習慣上這兩個引數寫為argc和argv。因此,main函式的函式頭可寫為 main argc,argv 語言還規...
c語言中的main函式討論
從剛開始寫c程式,相比大家便開始寫main 了。雖然無數的教科書和老師告訴我們main是程式的入口。那麼main函式是怎麼被呼叫的,怎麼傳入引數,返回的內容到 了,返回的內容是什麼?接下來我們來 一下這個問題。main 函式的形式 早期教材這麼寫 void main 其實翻翻c c 標準,從來沒有定...