Windows11 64位下NASM编写的Hello World无法输出求助
问题原因与解决方案
你的代码是Linux x86_64平台的系统调用实现,但在Windows 11环境下完全不兼容,所以无法输出内容。Windows和Linux的系统调用机制、程序入口规范都完全不同,以下是两种可行的修复方案:
方案1:调用C运行时库(MSVCRT)的printf函数(简单易上手)
修改后的汇编代码:
extern printf extern exit section .data msg db 'Hello, world!', 0xA, 0 ; C风格字符串必须以0字节结尾 section .text global main main: ; Windows x86_64调用约定:第一个参数放入RCX寄存器 mov rcx, msg call printf ; 调用exit函数退出程序,参数0表示正常退出 mov rcx, 0 call exit
编译命令(需要链接MSVCRT库):
nasm -f win64 main.asm ld -o main.exe main.obj -lmsvcrt
方案2:调用Windows原生API(WriteConsoleA)
如果不想依赖C运行时库,可以直接调用Windows内核API实现输出:
extern GetStdHandle extern WriteConsoleA extern ExitProcess section .data msg db 'Hello, world!', 0xA len equ $ - msg written dd 0 ; 存储实际写入的字节数 section .text global main main: ; 获取标准输出句柄,STD_OUTPUT_HANDLE的数值为-11 mov rcx, -11 call GetStdHandle ; 调用WriteConsoleA:参数依次为句柄、缓冲区、长度、写入数指针、预留参数 mov rcx, rax mov rdx, msg mov r8, len mov r9, written push 0 call WriteConsoleA ; 正常退出程序 mov rcx, 0 call ExitProcess
编译命令(需要链接kernel32库):
nasm -f win64 main.asm ld -o main.exe main.obj -lkernel32
关键说明
- 程序入口:Windows PE程序的标准入口不是
_start,而是main(配合C运行时)或自定义入口(需链接器指定),直接用_start会导致程序加载异常。 - 调用约定:Windows x86_64采用fastcall调用约定,前4个参数依次放入RCX、RDX、R8、R9寄存器,和Linux的调用约定完全不同。
- 系统调用差异:Linux通过
syscall指令直接触发内核调用,而Windows的系统调用需通过ntdll.dll封装,直接使用Linux的syscall号完全无效。
内容的提问来源于stack exchange,提问作者imbadatmath
相关产品推荐
相关产品推荐

