问题出在Windows的Ubuntu(Linux的Windows子系统)上。它仅支持64位
syscall接口, 不
int0x80支持32位x86系统调用机制。
除了无法
int0x80在64位二进制文件中使用(32位兼容性)之外,Windows上的Ubuntu(WSL)也不支持运行32位可执行文件。
您需要从使用转换
int0x80为
syscall。不难
a使用一组不同的寄存器,
syscall并且系统调用号与其32位对应号不同。Ryan
Chapman的博客中包含有关
syscall界面,系统调用及其参数的信息。
Sys_write并
Sys_exit以这种方式定义:
%rax System call %rdi %rsi %rdx%r10 %r8 %r9
0 sys_read unsigned int fd char *buf size_t count 1 sys_write unsigned int fd const char *buf size_t count60 sys_exit int error_pre
使用
syscall也则会覆盖 RCX 和 R11 寄存器。它们被认为是易变的。结束后不要依赖于它们具有相同的值
syscall。
您的代码可以修改为:
section .text global _start ;must be declared for linker (ld)_start: ;tells linker entry point mov edx,len ;message length mov rsi,msg ;message to write mov edi,1 ;file descriptor (stdout) mov eax,edi ;system call number (sys_write) syscall ;call kernel xor edi, edi ;Return value = 0 mov eax,60 ;system call number (sys_exit) syscall ;call kernelsection .data msg db 'Hello, world!', 0xa ;string to be printed len equ $ - msg ;length of the string
注意:在64位代码中,如果指令的 目标 寄存器是32位(例如 EAX , EBX , EDI , ESI
等),则处理器零会将结果扩展到
64位寄存器的高32位。
movedi,1具有与相同的效果
mov rdi,1。
这个答案不是编写64位代码的入门,仅是关于使用
syscall接口的。如果您对编写调用 C 库并符合64位System V
ABI的代码的细微差别感兴趣,那么可以使用Ray
Toal的NASM教程之类的合理教程来入门。他讨论了堆栈对齐,红色区域,寄存器使用情况以及64位System
V调用约定的基本概述。



