linux汇编“;collect2:ld返回1退出状态“;

linux汇编“;collect2:ld返回1退出状态“;,linux,gcc,assembly,x86,linker-errors,Linux,Gcc,Assembly,X86,Linker Errors,我在一个在线编码网站上输入了源代码 但我在源代码下面发现了错误 我想我省略了“main” 自从我学会了英特尔assmbly,我不知道如何修复它 你能帮我吗 谢谢你提前帮助我 SECTION .DATA hello: db 'Hello world!',10 helloLen: equ $-hello SECTION .TEXT GLOBAL _START _START: ; Write 'Hello world!' to the screen mov e

我在一个在线编码网站上输入了源代码

但我在源代码下面发现了错误

我想我省略了“main”

自从我学会了英特尔assmbly,我不知道如何修复它

你能帮我吗

谢谢你提前帮助我

SECTION .DATA
    hello:     db 'Hello world!',10
    helloLen:  equ $-hello

SECTION .TEXT
    GLOBAL _START

_START:


; Write 'Hello world!' to the screen
mov eax,4            ; 'write' system call
mov ebx,1            ; file descriptor 1 = screen
mov ecx,hello        ; string to write
mov edx,helloLen     ; length of string to write
int 80h              ; call the kernel

; Terminate program
mov eax,1            ; 'exit' system call
mov ebx,0            ; exit with error code 0
int 80h              ; call the kernel
/usr/lib/gcc/i686 linux gnu/4.6/../../../..//i386 linux gnu/crt1.o:在函数
\u start'中:
(.text+0x18):未定义对
main'的引用 collect2:ld返回了1个退出状态

如果您只是将GCC用作链接器,而不关心C运行时,那么您可以通过将
-nostlib
传递给GCC来排除它(正如Jester指出的)。然后需要提供一个
\u start
符号,使代码看起来像:

SECTION .DATA
    hello:     db 'Hello world!',10
    helloLen:  equ $-hello

SECTION .TEXT
    GLOBAL _start

_start:
; Write 'Hello world!' to the screen
    mov eax,4            ; 'write' system call
    mov ebx,1            ; file descriptor 1 = screen
    mov ecx,hello        ; string to write
    mov edx,helloLen     ; length of string to write
    int 80h              ; call the kernel

    ; Terminate program
    mov eax,1            ; 'exit' system call
    mov ebx,0            ; exit with error code 0
    int 80h              ; call the kernel
您可以这样组装和链接它:

nasm -f elf file.asm
gcc -m32 -nostdlib -o file file.o
EXTERN printf    ; Tell the assembler printf is provided outside our file

SECTION .DATA
    hello:     db 'Hello world!',10,0 ; Null terminate for printf
    helloLen:  equ $-hello-1          ; Exclude null by reducing len by 1

SECTION .TEXT
    GLOBAL main

; main is now a C function
main:
    push ebp              ; Setup stack frame
    mov  ebp, esp
    push ebx              ; We need to preserve EBX (C Calling convention)

    ; Write 'Hello world!' to the screen
    mov eax,4            ; 'write' system call
    mov ebx,1            ; file descriptor 1 = screen
    mov ecx,hello        ; string to write
    mov edx,helloLen     ; length of string to write
    int 80h              ; call the kernel

    ; Write 'Hello World!' with C printf
    push hello           ; push the address of string to print
    call printf          ; call printf in C library
    add esp, 4           ; Restore stack pointer
                         ; push hello pushed 4 bytes on stack

    mov  eax, 0x0        ; Return value of 0
    pop  ebx             ; Restore EBX
    leave
    ret                  ; Return to C runtime which will cleanup and exit
或者,您可以直接链接到
ld
,也可以这样做:

nasm -f elf file.asm
ld -melf_i386 -o file file.o
这将生成一个名为
file
32位Linux可执行文件

使用C库/运行时 虽然我不认为以下是您的意图,但有些人可能会发现以下信息很有用:

通过将
\u START
重命名为
main
,可以使用GCC并使C库可用于汇编代码。C运行时包含一个名为
\u start
的入口点,该入口点处理初始化,然后调用名为
main
的函数。您可以利用C库,但
main
必须正确设置堆栈框架,并正确清理堆栈框架,完成后返回,因为
main
将被视为C函数。代码如下所示:

nasm -f elf file.asm
gcc -m32 -nostdlib -o file file.o
EXTERN printf    ; Tell the assembler printf is provided outside our file

SECTION .DATA
    hello:     db 'Hello world!',10,0 ; Null terminate for printf
    helloLen:  equ $-hello-1          ; Exclude null by reducing len by 1

SECTION .TEXT
    GLOBAL main

; main is now a C function
main:
    push ebp              ; Setup stack frame
    mov  ebp, esp
    push ebx              ; We need to preserve EBX (C Calling convention)

    ; Write 'Hello world!' to the screen
    mov eax,4            ; 'write' system call
    mov ebx,1            ; file descriptor 1 = screen
    mov ecx,hello        ; string to write
    mov edx,helloLen     ; length of string to write
    int 80h              ; call the kernel

    ; Write 'Hello World!' with C printf
    push hello           ; push the address of string to print
    call printf          ; call printf in C library
    add esp, 4           ; Restore stack pointer
                         ; push hello pushed 4 bytes on stack

    mov  eax, 0x0        ; Return value of 0
    pop  ebx             ; Restore EBX
    leave
    ret                  ; Return to C runtime which will cleanup and exit
本例使用
int0x80
系统调用写入标准输出,并使用C
printf
执行相同的操作。您可以使用以下工具组合并链接到名为
文件的可执行文件:

nasm -f elf file.asm
gcc -m32 -o file file.o

gcc-nostlib
还请确保您以小写形式调用您的入口点
\u start
。非常感谢。第二本在网站上很有用。你能推荐一本学习linux汇编的书吗?我读过基普·R·欧文。但它是针对基于英特尔的计算机的。您使用的代码是针对与英特尔兼容的计算机的。也许你的意思是Kip R Irvine材料是针对Windows的,而你正在寻找Linux材料。我实际上没有任何关于这个问题的书籍,所以我不能提出建议,但是你可能想把这个在线教程作为一个起点: