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
而不是 1
但 4
是在 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
我在 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
而不是 1
但 4
是在 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