nasm 写入系统调用不适用于 64 位版本如何解决?

nasm write system call not working for 64 bit version how to resolve?

我在 nasm 中编写了简单的 hello_world 程序。

segment .text               ; code section
    global _start           ; must be declared for linker

    _start:                 ; tell linker entry point
        mov edx, len        ; message len (DX is for data register)
        mov ecx, msg        ; message to write (CX is for count register)
        mov ebx, 1          ; (stdout) file descriptor
        mov eax, 1          ; system call number for write system call
        int 0x80            ; call kernel

        mov eax, 1          ; system call number for exit system call
        int 0x80            ; call kernel

section .data
    msg db "Hello, World", 0xa
    len equ $ - msg

所以当我用 elf64 标志编译这个程序时 $nasm -f elf64 hello_world.nasm

然后链接到 ld $ld hello_world.o

最后当我 运行 a.out 它没有写任何东西到 stdout.

当我打开文件 unistd_64.h 以显示哪个系统调用正在调用 1.

// /usr/include/asm/unistd_64.h

#ifndef _ASM_X86_UNISTD_64_H
#define _ASM_X86_UNISTD_64_H 1

#define __NR_read 0
#define __NR_write 1
#define __NR_open 2
#define __NR_close 3
#define __NR_stat 4

如您所见,写入系统调用号是1。如果我把 4 而不是 14 是在 unistd_32.h 中指定的,并且我还使用 elf64 标志编译,那么这个程序将工作所以为什么它不工作64 bit?

供大家参考unistd_32.h

#ifndef _ASM_X86_UNISTD_32_H
#define _ASM_X86_UNISTD_32_H 1

#define __NR_restart_syscall 0
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4

您犯了一个错误,您需要使用 sysv-64-abi 声明要传递给 rdi、rsi、rdx、rcx 的函数参数。另外 exit 系统调用号是十进制的 60 而不是 1。你也打错了 section .text。任何你需要使用 syscall 而不是旧的更慢的 int 软中断指令来陷入内核。

section .text               ; code section
    global _start           ; must be declared for linker

    _start:                 ; tell linker entry point
        mov rdx, len        ; message len (DX is for data register)
        mov rsi, msg        ; message to write (CX is for count register)
        mov rdi, 1          ; (stdout) file descriptor
        mov rax, 1          ; system call number for write system call
        syscall            ; call kernel

        mov rax, 60          ; system call number for exit system call
        syscall            ; call kernel

section .data
    msg db "Hello, World", 0xa
    len equ $ - msg