Hello world printf在程序集中出现问题

时间:2015-06-21 04:03:58

标签: assembly

我一直在寻找如何解决这个问题的几个小时。通过键入

运行它
nasm -f elf64  hello.asm
ld -s -o hello hello.o

并获得以下内容:

ld: warning: cannot find entry symbol _start; defaulting to 00000000004000b0
hello.o: In function `main':
hello.asm:(.text+0x12): undefined reference to `printf'

如果我gcc hello.o,那么./a.out就可以了,但随后存储库中会有一个额外的.a文件。

对此非常陌生,在压缩的夏季课程中,教授正在让我们学习Linux和github来完成我们的任务!关于我做错什么的任何想法?

;hello.asm

    bits 64
    global main
    extern printf

    section .text
main:
    ; function setup
    push    rbp
    mov     rbp, rsp
    sub     rsp, 32
    ;
    lea     rdi, [rel message]
    mov     al, 0
    call    printf

    ; function return
    mov     eax, 0
    add     rsp, 32
    pop     rbp
    ret

    section .data
message: db      'Course: COSC2425 Lab2',0x0D,0x0a,'Student: firstname     lastname',0x0D,0x0a,'Project: Nasm Hello World'

2 个答案:

答案 0 :(得分:0)

Haven没有使用nasm,但是使用气体程序如下。创建对象:

as -o hello.o hello.s

现在,因为你正在调用printf链接是针对ld-linux.so.2,根据Richard Bloom或调整为64位架构

ld --dynamic-linker /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 -o hello -lc hello.o

仔细检查ld-linux-x86-64.so.2的正确位置在你的Linux中可能在其他地方。顺便说一句,你的代码在退出时是segfaulting。只有这样才能让它正常退出:

    global _start
    extern printf
    section .text
_start:
    mov     rdi, format
    mov     rsi, message
    mov     rax, 0
    call    printf
    mov rax, 1
    mov rbx, 0
    int 80h
    section .data
message: db      'Course: COSC2425 Lab2',0x0a,'Student: firstname     lastname',0x0a,'Project: Nasm Hello World',0x0a,0
format:    db '%s', 0

main重命名为_start以消除链接器警告。

答案 1 :(得分:0)

printf是标准C库的一部分。使用gcc编译程序会在链接时自动添加此库。如果您手动使用ld,则需要将库与程序链接。试试这个:

ld -I/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 -lc -s -o hello hello.o

此外,默认情况下,ld将查找名为_start的全局标签,这是程序执行开始的地方。您需要将global main更改为global _start,将main:更改为_start:,或者您需要通过以下方式告知ld您的计划开始位置:

ld -I/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 -lc -e main -s -o hello hello.o