我的Hello World汇编代码无法运行,求Windows 11环境下解决方法
Windows下NASM编译Linux汇编代码无输出问题解决
我参考Fireship的视频写了一段汇编代码,代码如下:
section .bss ; variables section .data: ; constants hello: db "Hi Mom!" helloLen: equ $-hello section .text global _start _start: mov rax, 1 mov rdi, 1 mov rsi, hello mov rdx, helloLen syscall mov rax, 60 mov rdi, 0 syscall
在Windows 11系统下用NASM编译、GNU linker链接后,程序无任何输出。只能在VSCode终端通过./app执行,但CMD无法识别该文件(推测因不是.exe格式)。怀疑是视频用Linux环境而我用Windows导致的问题,不确定是否必须在Linux运行,寻求解决办法。
我的环境:Windows 11、NASM、GNU linker
编译链接命令:nasm -f elf64 app.asm(尝试win64格式也无效)ld -o app app.o
运行命令:./app
问题原因
你编写的是Linux x86_64架构的汇编代码,核心依赖Linux的系统调用接口:
rax=1对应Linux的write系统调用,用来输出内容到控制台rax=60对应Linux的exit系统调用,用来终止程序
而Windows和Linux的系统调用机制、可执行文件格式完全不同:
- Linux使用ELF格式可执行文件,Windows使用PE格式(.exe),所以CMD无法识别你用
ld生成的ELF文件 - Windows没有Linux的
write/exit系统调用,直接在Windows原生环境运行Linux汇编代码会因为系统调用不匹配导致无输出或程序异常
VSCode终端能执行./app但无输出,大概率是终端通过兼容层尝试运行,但无法正确映射Linux系统调用到Windows API,所以没有预期结果。
解决办法
方法一:使用WSL(Windows子系统Linux)运行
这是最简单的方案,无需修改代码:
- 安装WSL(比如Ubuntu发行版),打开WSL终端
- 在WSL中安装NASM和GNU linker:
sudo apt install nasm ld - 重新编译链接代码:
nasm -f elf64 app.asm ld -o app app.o - 运行
./app即可看到Hi Mom!的输出
方法二:修改代码适配Windows系统
如果要在Windows原生环境运行,需要编写适配Windows x64的汇编代码,调用Win32 API实现输出。示例代码如下:
section .data hello db 'Hi Mom!', 0dh, 0ah ; 0dh=回车,0ah=换行 helloLen equ $ - hello section .text global main extern GetStdHandle, WriteConsoleA, ExitProcess main: ; 1. 获取标准输出句柄(STD_OUTPUT_HANDLE = -11) mov rcx, -11 call GetStdHandle ; 2. 调用WriteConsoleA写入控制台 mov rcx, rax ; 第一个参数:输出句柄 mov rdx, hello ; 第二个参数:要输出的字符串地址 mov r8, helloLen ; 第三个参数:字符串长度 sub rsp, 8 ; 栈对齐(Windows x64调用约定要求栈16字节对齐) mov r9, rsp ; 第四个参数:接收实际写入字节数的指针 call WriteConsoleA add rsp, 8 ; 恢复栈 ; 3. 调用ExitProcess退出程序 mov rcx, 0 call ExitProcess
编译链接需要使用MinGW工具链(因为要链接Windows的kernel32.dll):
nasm -f win64 app.asm -o app.obj gcc app.obj -o app.exe -lkernel32
编译完成后,在CMD或PowerShell中运行app.exe即可看到输出。
内容的提问来源于stack exchange,提问作者Pygameuserr
相关产品推荐
相关产品推荐

