正如我在评论中所写,x86_64 使用与 32 位 Linux 不同的系统调用方法。尤其int $0x80
不再是这样做的方法(尽管如果您安装了 32 位库,它可能会半工作......)。例如参见这个之前的讨论.
在 32 位 x86 上,您会执行以下操作:
mov eax, SYSCALL_NUMBER
mov ebx, first_param
mov ecx, second_param
mov edx, third_param
int 0x80
您应该在 x86_64 上执行以下操作:
mov rax, SYSCALL_NUMBER_64 ; This is usually different from the 32-bit version!
mov rdi, first_param
mov rsi, second_param
mov rdx, third_param
syscall
要打印程序名称,请将程序更改为以下内容,它应该可以工作。对于对启动时程序环境的外观感兴趣的其他人,请参阅here.
section .text
global _start
_start:
mov rax, [rsp+8]
push rax
call strlen
add rsp, 8
mov rdi, 1 ; fd = stdout
mov rsi, [rsp+8] ; buf = addr to string
mov rdx, rax ; count = strlen(string)
mov rax, 1 ; write
syscall
mov rdi, 0 ; status = 0
mov rax, 60 ; exit
syscall
strlen:
mov rax, 0
mov rbx, [rsp+8]
strlen_loop:
cmp byte [rbx+rax], 0
je strlen_end
inc rax
jmp strlen_loop
strlen_end:
ret ; len in rax
编译使用:
nasm -g -f elf64 -o sc.o sc.asm
gcc -nostartfiles -o sc sc.o