为什么这个汇编程序没有输出?

Why does this assembly program produce no output?

作为 x86_64 程序集的新手,我正在尝试在笔记本电脑 运行 64 位 OpenBSD 上编写一个基本的 "hello" 程序。该程序运行完成,退出代码为 0,但似乎忽略了将文本写入标准输出的系统调用。为什么?

我正在使用 GNU 汇编程序并创建可执行文件:

as -o hello.o hello.s; ld -Bstatic hello.o

# OpenBSD ELF identification
.section ".note.opensd.ident", "a"
.p2align 2
.long 0x8
.long 0x4
.long 0x1
.ascii "OpenBSD[=10=]"
.long 0x0
.p2align 2

.section .data
msg: .ascii "hello"

.section .text
.globl _start
_start:
    push  # number of bytes to write
    push $msg # message address
    push  # file descriptor 1 for stdout
    mov , %eax # write is system call 4
    syscall

    push [=10=] # exit code 0
    mov , %eax # exit is system call 1
    syscall

因为您标记 x86_64 并且可能在 x86_64 系统上。因此你需要:

  • 作为--64
  • 使用 pushq 而不是 pushl 将 64 位值压入堆栈
  • 在系统调用之前将这些值传输到适当的寄存器

    .section ".note.opensd.ident", "a"
    .p2align 2
    .long 0x8
    .long 0x4
    .long 0x1
    .ascii "OpenBSD[=10=]"
    .long 0x0
    .p2align 2
    
    .section .data
     msg: .ascii "hello"
    
    .section .text
    .globl _start
    _start:
            pushq [=10=]x4
            popq %rax               # 4 (write syscall) into rax
            pushq [=10=]x1
            popq %rdi               # 1 (STDOUT) into rdi
            pushq $msg
            popq %rsi               # address of hello msg into rsi
            pushq [=10=]x5
            popq %rdx               # length of hello msg into rdx
            syscall
            pushq 
            popq %rax
            pushq [=10=]
            popq %rdi
            syscall
    

以下文章提供了一些有用的信息:

x64 asm on FreeBSD

differences between x86 and x64 asm