1. 程式人生 > >Ubuntu 16.04下使用gcc輸出匯編的.0文件為可執行文件時出現:`_start'被多次定義

Ubuntu 16.04下使用gcc輸出匯編的.0文件為可執行文件時出現:`_start'被多次定義

file blank pan art 一次 x86_64 另一個 使用 urn

錯誤如下:

`_start‘被多次定義
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o:(.text+0x0):第一次在此定義
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o:在函數‘_start’中:
(.text+0x20):對‘main’未定義的引用
collect2: error: ld returned 1 exit status

問題分析:

可以看到錯誤信息提示,提到了一個“crt1.o”這個文件,其中crt是“C runtime library”的縮寫,其含義是“C運時庫”。

C運行時庫除了給我們提供必要的庫函數調用(如memcpy、printf、malloc等)之外,它提供的另一個最重要的功能是為應用程序添加啟動函數。C運行時庫啟動函數的主要功能為進行程序的初始化,對全局變量進行賦初值,加載用戶程序的入口函數。

從給出的錯誤提示信息中還可以得知,在crt1.o中,有一個名為“_start”的函數。現在網上找到一份crt1.o的偽代碼:

    section .text:
    __start:
    
     :
     init stack;
     init heap;
     open stdin
;      open stdout;      open stderr;      :      push argv;      push argc;      call _main; (調用 main)      :      destory heap;      close stdin;      close stdout;      close stderr;      :      call __exit;

從偽代碼可以看出,在這個_start函數中,調用了main函數。那麽我們可以去修改入口函數,把入口函數改成junco。

執行下面的命令:

gcc 1.c -e junco -nostartfiles

其中-e選項為修改函數的入口地址。-e指的就是entrance。這裏把entrance指定為junco函數。-nostartfiles選項的作用是通知編譯器不自動加入啟動函數以及別的庫級別的初始化,這樣就不會調用到crt1.o中的_start函數。

參考:

http://blog.sina.com.cn/s/blog_76a864e20101ehtp.html(以上問題分析來自此篇文章,但是是講C語言的,而上面的方法也同樣適用匯編)

Ubuntu 16.04下使用gcc輸出匯編的.0文件為可執行文件時出現:`_start'被多次定義