You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

关键说明

  1. 程序入口:Windows PE程序的标准入口不是_start,而是main(配合C运行时)或自定义入口(需链接器指定),直接用_start会导致程序加载异常。
  2. 调用约定:Windows x86_64采用fastcall调用约定,前4个参数依次放入RCX、RDX、R8、R9寄存器,和Linux的调用约定完全不同。
  3. 系统调用差异:Linux通过syscall指令直接触发内核调用,而Windows的系统调用需通过ntdll.dll封装,直接使用Linux的syscall号完全无效。

内容的提问来源于stack exchange,提问作者imbadatmath

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 14:16:07