[英]Compile and run program without main() in C
我正在嘗試在C
編譯和運行不帶main()
函數的以下程序。 我已經使用以下命令編譯了程序。
gcc -nostartfiles nomain.c
編譯器發出警告
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000400340
好,沒問題 然后,我運行了可執行文件(a.out),兩個printf
語句均成功打印,然后出現分段錯誤 。
因此,我的問題是, 為什么成功執行打印語句后出現分段錯誤?
我的代碼:
#include <stdio.h>
void nomain()
{
printf("Hello World...\n");
printf("Successfully run without main...\n");
}
輸出:
Hello World...
Successfully run without main...
Segmentation fault (core dumped)
注意:
在這里, -nostartfiles
gcc標志可防止編譯器在鏈接時使用標准啟動文件
讓我們看一下程序的生成程序集 :
.LC0:
.string "Hello World..."
.LC1:
.string "Successfully run without main..."
nomain:
push rbp
mov rbp, rsp
mov edi, OFFSET FLAT:.LC0
call puts
mov edi, OFFSET FLAT:.LC1
call puts
nop
pop rbp
ret
請注意ret
語句。 您的程序的入口確定為nomain
,一切都很好。 但是一旦函數返回,它就會嘗試跳轉到調用堆棧中的一個地址中...未填充。 這是非法訪問,然后出現分段錯誤。
一種快速的解決方案是在程序的末尾調用exit()
(並假設C11我們最好將該函數標記為_Noreturn
):
#include <stdio.h>
#include <stdlib.h>
_Noreturn void nomain(void)
{
printf("Hello World...\n");
printf("Successfully run without main...\n");
exit(0);
}
實際上,現在您的函數的行為與常規的main
函數非常相似,因為從main
返回后,將使用main
的返回值調用exit
函數。
在C語言中,當調用函數/子例程時,堆棧填充為(按順序):
main()是起點,ELF構造程序的方式是,首先執行的任何指令都將首先被推送,在這種情況下,printfs會被推送。
現在,程序被截斷了一些,沒有返回地址或__end__
,實際上它假定那個( __end__
)位置的堆棧上的任何內容都是返回地址,但不幸的是它沒有,因此崩潰了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.