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

Windows11下NASM编译x86汇编生成exe遇WinMain@16未定义错误求助

问题排查:Windows下汇编Hello World链接报错WinMain@16未定义

问题描述

你编写的x86汇编代码如下:

section .data
    msg db 'Hello World', 0x0A
    msg_len equ $ - msg

section .text
    global _start

_start:
    mov eax, 4
    mov ebx, 1
    mov ecx, msg
    mov edx, msg_len
    int 0x80

    mov eax, 1
    xor ebx, ebx
    int 0x80

使用命令nasm -fwin32 hello_world.asm编译为.obj文件后,执行gcc hello_world.obj链接时出现错误:

c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../libmingw32.a(main.o):(.text.startup+0xa0): undefined reference to `WinMain@16'
collect2.exe: error: ld returned 1 exit status

错误原因

  • 你的代码采用的是Linux x86平台的系统调用规范:int 0x80是Linux下触发系统调用的指令,_start是Linux程序的默认入口点,这套逻辑在Windows系统下完全不兼容。
  • GCC链接器在Windows环境下,默认会寻找控制台程序入口main或GUI程序入口WinMain@16,但你的代码定义的是Linux风格的_start,导致链接器找不到合法入口,抛出错误。

解决方案

方案1:改用Windows兼容的C标准库入口(推荐,适合新手)

修改代码为调用C标准库的printf函数,适配Windows链接规则:

section .data
    msg db 'Hello World', 0x0A, 0  ; 注意添加字符串结束符0,符合C标准库要求

section .text
    global main
    extern _printf  ; 声明外部C标准库函数

main:
    push msg         ; 传递printf的参数
    call _printf     ; 调用printf输出字符串
    add esp, 4       ; 清理栈(因为push了4字节的参数)

    mov eax, 0       ; 返回0表示程序正常结束
    ret

编译链接命令:

nasm -fwin32 hello_world.asm && gcc hello_world.obj -o hello_world.exe

方案2:强制链接器使用_start作为入口(仅解决链接问题,代码需适配Windows系统调用)

如果想保留_start入口,可通过GCC参数指定链接器忽略默认入口,命令改为:

gcc hello_world.obj -o hello_world.exe -nostartfiles

但注意:原代码中的int 0x80系统调用在Windows下无效,执行会崩溃,必须把Linux系统调用替换为Windows的系统调用或API(比如WriteFile,需处理句柄等细节,相对复杂)。

内容的提问来源于stack exchange,提问作者Felix Hötzendorfer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 11:10:20