2014-11-21 48 views
1

我一直在關注this tutorial以便在Linux上進行彙編。Linux上的NASM Hello World:對'main'的未定義引用

section .text 
global _start ;must be declared for linker (ld) 

_start: 
     mov edx,len  ;message length 
     mov ecx,msg  ;message to write 
     mov ebx,1  ;file descriptior 
     mov eax,4  ;system call number (sys_write) 
     int 0x80  ;call kernel 

     mov eax,1  ;system call number (sys_exit) 
     int 0x080  ;call kernel 

section .data 

msg db 'Hello, world!', 0xa  ;the string 
len equ $ - msg     ;length of the string 

我在編譯它時遇到了問題。我環顧四周,發現(在SO),我應該編譯如下:

nasm -f elf64 hello.asm 
gcc -o hello hello.o 

,但我一直從GCC收到此錯誤:

hello.o: In function `_start': 
hello.asm:(.text+0x0): multiple definition of `_start' 
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o:(.text+0x0): first defined here 
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o: In function `_start': 
(.text+0x20): undefined reference to `main' 
collect2: error: ld returned 1 exit status 

(注:我運行Debian Linux在64位英特爾i7上)

回答

4

鏈接二進制文件時,應該添加-nostdlib

gcc -o hello hello.o -nostdlib 
+0

你需要用'GCC -m32 -nostdlib -o你好hello.o輪候冊,-melf_i386'否則鏈接將失敗或產生一個非工作的可執行文件。 – 2014-11-21 01:02:35

+0

我不知道我明白。爲什麼我想要鏈接器從'elf64-x86-64'目標文件生成'elf32-i386'可執行文件? – xbug 2014-11-21 01:17:41

7

如果你要學習彙編,那麼你的服務要好得多學習使用匯編nasm和連接ld不依靠gcc。使用gcc沒有任何問題,但是它掩蓋了您需要了解未來的部分鏈接過程。

在當前的環境下(通常建立在x86_64,但使用的是寫在x86 32-bit彙編的例子)學習組件,你必須學會​​建立正確的目標和語言(syscall)兩者之間的差異。你的代碼示例是32-bit彙編器。這樣你nasm編譯字符串是不正確的:

nasm -f elf64 hello.asm 

-f elf64嘗試編譯64-bit目標文件,但在你的代碼的指令是32-bit指令。 (它不起作用)

理解和使用ld可以更好地理解差異。您可以使用nasmld來完成同樣的事情,而不是使用gcc。例如(略有修改的代碼):

msg db 0xa, 'Hello, StackOverflow!', 0xa, 0xa  ;the string 

您編譯和構建:

nasm -f elf -o hello-stack_32.o hello-stack_32.asm 
ld -m elf_i386 -o hello-stack_32 hello-stack_32.o 

注意nasm呼叫使用-f elf32-bit代碼和-m elf_i386鏈接器選項創建兼容的可執行文件。

輸出:

Hello, StackOverflow! 

如果你是認真學習彙編,還有一些在網絡上很好的參考。最好的之一是The Art of Assembly。 (它主要是爲8086x86寫的,但它提供的基礎是無價的)。另外,查看用二進制文件創建的可執行文件可能會有幫助。看看Binary Vi (BVI)。這是一個好工具。

BVI截圖

enter image description here

+0

我不知道BVI。 BVI在hexeditor模式下使用VIM有什麼優勢? – 2014-11-21 09:59:21

+0

在二進制文件中,沒有'newline'的概念。 'bvi'是爲這個環境量身定製的,並且提供'hex'&'ASCII'並排顯示。很值得看。 IIRC,它是一個CMake版本,所以從源代碼構建是微不足道的。 – 2014-11-21 10:22:28

+0

我的意思是,它與做'vim -b a.out'然後':%!xxd'不同。這顯示了十六進制和ASCII並排。 – 2014-11-21 13:43:07

相關問題