0

作为 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\0"
.long 0x0
.p2align 2

.section .data
msg: .ascii "hello"

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

    push $0 # exit code 0
    mov $1, %eax # exit is system call 1
    syscall
4

1 回答 1

0

由于您标记 x86_64 并且可能在 x86_64 系统上。因此,您需要:

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

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

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

FreeBSD 上的 x64 asm

x86 和 x64 asm 的区别

于 2015-01-11T01:25:56.457 回答