Linux 程序集 "collect2: ld returned 1 exit status"

标签 linux gcc assembly x86 linker-errors

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

但是我在源代码下面有错误。

我想我省略了“main”。

自从学了intel 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: 在函数 _start' 中: (.text+0x18):对 main' 的 undefined reference collect2: ld 返回 1 个退出状态

最佳答案

如果您只是将 GCC 用作链接器并且不关心 C 运行时,那么您可以通过传递 -nostdlibgcc 。然后您需要提供一个 _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

或者,您可以直接链接到 ld,这样您也可以这样做:

nasm -f elf file.asm
ld -melf_i386 -o file file.o

这将生成一个名为 file 的 32 位 Linux 可执行文件

使用 C 库/运行时

虽然我认为以下内容不是您想要的,但有人可能会发现以下信息有用:

您可以使用 GCC 并通过将 _START 重命名为 mainC 库可用于您的汇编代码. C 运行时包含一个名为 _start 的入口点,它处理初始化,然后调用一个名为 main 的函数。您可以利用 C 库,但 main 必须正确设置堆栈框架并正确清理它并在完成后返回,因为 main 将被视为 C 函数。代码看起来像这样:

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

这个例子使用 int 0x80 系统调用来写标准输出,并使用 C printf 来做同样的事情。您可以使用以下命令汇编并链接到名为 file 的可执行文件:

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

关于Linux 程序集 "collect2: ld returned 1 exit status",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33420741/

相关文章:

python - libao 示例在编译为 python 模块时不起作用

c++ - 试图修复转换警告

assembly - Dlang - 理解汇编中的 std.cycle()

assembly - 两个数组的总和,每个数组 n 个字节

linux - DocumentRoot 文件夹名称中的空格

linux - 生成具有文件读取权限的用户列表

c - 编译器优化应用于哪个级别?

c# - 为什么 typeA == typeB 比 type == typeof(Type B) 慢?

linux - 如何将源文件中的文本复制并粘贴到新文件(仅数字)?

linux - docker run hello-world 仍然失败,权限被拒绝