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

NASM汇编代码转.obj后用GCC生成.exe遇WinMain未定义错误

问题解决方法

核心问题分析

  • 你的汇编代码是Linux x86_64平台的系统调用实现,但你在Windows环境下使用MinGW-GCC编译,Windows的系统调用机制与Linux完全不同,mov rax,1(对应Linux的write调用)、mov rax,60(对应Linux的exit调用)都是Linux专属的系统调用号,Windows无法识别。
  • MinGW-GCC默认会链接C运行时库(CRT),CRT会自动寻找WinMain或main作为程序入口,而你的代码入口是_start,因此触发链接错误。

解决方案

方案1:修改代码适配Windows平台

Windows控制台程序需要调用Windows API实现输入输出和退出逻辑,而非直接使用Linux风格的syscall。以下是适配Windows x64的Hello World汇编代码:

section .data
    hello db 'Hello, World!', 0Dh, 0Ah  ; 追加回车换行符
    hello_len equ $ - hello

section .text
    global main
    extern GetStdHandle, WriteConsoleA, ExitProcess

main:
    ; 获取标准输出句柄
    mov rcx, -11  ; 对应STD_OUTPUT_HANDLE常量
    call GetStdHandle

    ; 写入字符串到控制台
    mov rcx, rax                ; 传入输出句柄
    mov rdx, hello              ; 传入字符串地址
    mov r8, hello_len           ; 传入字符串长度
    sub rsp, 8                  ; 栈对齐(Windows x64调用约定要求栈保持16字节对齐)
    mov r9, rsp                 ; 传入接收实际写入字节数的指针
    call WriteConsoleA
    add rsp, 8

    ; 退出程序
    mov rcx, 0                  ; 传入退出码0
    call ExitProcess

编译链接命令:

nasm -f win64 hello.asm -o hello.obj
gcc hello.obj -o hello.exe

方案2:直接用ld链接,跳过CRT

若仅想解决链接错误(注意:生成的程序在Windows下无法正常运行,因为Linux syscall在Windows中无效),可使用MinGW的ld直接链接,指定入口为_start并跳过CRT:

nasm -f win64 hello.asm -o hello.obj
ld hello.obj -o hello.exe --entry=_start -lkernel32

方案3:使用WSL编译运行Linux程序

如果你的目标是编写Linux平台的汇编代码,建议使用Windows Subsystem for Linux(WSL):

  1. 启用WSL并安装Linux发行版(如Ubuntu)
  2. 在WSL终端中执行编译运行命令:
nasm -f elf64 hello.asm -o hello.o
ld hello.o -o hello
./hello

额外说明

  • gdb是调试工具,并非编译链接工具,因此不识别-o参数。需先通过gcc/ld生成exe后,再用gdb hello.exe启动调试。
  • MinGW的g++与gcc行为一致,默认都会链接CRT,因此报相同错误属于正常现象。

内容的提问来源于stack exchange,提问作者Θάνος Δριβάκος

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 07:15:07