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

x64 Windows下NASM编写无C库依赖Hello World遇阻求助

可行的x64 Windows NASM无C库依赖Hello World实现方案

方案1:弹窗版(MessageBoxA)

以下代码直接调用Windows API,无任何C库依赖,可通过NASM编译+GoLink/MSVC Link链接:

; hello.asm
bits 64
default rel

; 声明导入的API符号(通过导入表引用)
extern __imp_MessageBoxA
extern __imp_ExitProcess

section .data
    title   db 'Hello', 0
    msg     db 'Hello World!', 0

section .text
; 程序入口(x64 Windows默认入口名不是main,需显式指定)
global Start
Start:
    ; MessageBoxA(hWnd=NULL, lpText, lpCaption, uType=MB_OK)
    xor     rcx, rcx        ; 第1个参数:窗口句柄设为NULL
    lea     rdx, [msg]      ; 第2个参数:消息文本(RIP相对寻址)
    lea     r8, [title]     ; 第3个参数:弹窗标题
    mov     r9d, 0x00000000 ; 第4个参数:弹窗类型为MB_OK
    call    [__imp_MessageBoxA] ; 间接调用导入的API

    ; ExitProcess(uExitCode=0)
    xor     rcx, rcx        ; 退出码设为0
    call    [__imp_ExitProcess]

编译链接命令

  • 编译:nasm -f win64 hello.asm -o hello.obj
  • GoLink链接:golink /entry Start hello.obj user32.dll kernel32.dll
  • MSVC Link链接:link hello.obj /subsystem:windows /entry:Start kernel32.lib user32.lib

方案2:控制台输出版(WriteConsoleA)

适合不需要弹窗的场景,仅依赖kernel32.dll:

; console_hello.asm
bits 64
default rel

extern __imp_GetStdHandle
extern __imp_WriteConsoleA
extern __imp_ExitProcess

section .data
    msg     db 'Hello World!', 0x0a, 0x0d ; 包含换行回车
    msg_len equ $ - msg ; 计算消息长度

section .text
global Start
Start:
    ; 获取标准输出句柄(STD_OUTPUT_HANDLE = -11)
    mov     rcx, -11
    call    [__imp_GetStdHandle]
    mov     rbx, rax ; 保存句柄到RBX

    ; WriteConsoleA(hConsole, msg, len, NULL, NULL)
    mov     rcx, rbx        ; 第1个参数:控制台句柄
    lea     rdx, [msg]      ; 第2个参数:输出文本
    mov     r8d, msg_len    ; 第3个参数:文本长度
    xor     r9, r9          ; 第4个参数:接收实际输出长度的指针(设为NULL)
    push    r9              ; 第5个参数:保留参数(x64调用约定中,前4个参数用寄存器,剩余压栈)
    call    [__imp_WriteConsoleA]
    add     rsp, 8          ; 清理栈空间

    ; 退出程序
    xor     rcx, rcx
    call    [__imp_ExitProcess]

编译链接命令

  • 编译:nasm -f win64 console_hello.asm -o console_hello.obj
  • GoLink链接:golink /console /entry Start console_hello.obj kernel32.dll
  • GCC链接:gcc console_hello.obj -o console_hello.exe -nostdlib -lkernel32 -e Start

你遇到的问题解决办法

1. 32位转64位无输出、语法错误不敏感

  • 调用约定不兼容:x64 Windows使用fastcall调用约定,前4个参数必须用RCX/RDX/R8/R9传递,剩余参数压栈,和32位的stdcall/cdecl完全不同,直接修改寄存器会导致API调用参数错误,无输出。
  • 目标格式错误:NASM编译时必须指定-f win64,否则默认生成ELF64格式文件,Windows链接器无法正确处理,且NASM对ELF格式的语法校验逻辑更宽松,导致“对语法错误不敏感”。

2. MessageBoxA未定义错误

  • 缺少依赖库:链接时必须显式指定user32.dll(GoLink)或user32.lib(MSVC/GCC),否则链接器找不到MessageBoxA的导出符号。
  • 符号名错误:x64下Windows API符号不需要加下划线,32位是_MessageBoxA,64位直接是MessageBoxA,且必须通过导入表的__imp_MessageBoxA间接调用,不能直接call MessageBoxA。

3. 重定位截断错误

  • 寻址方式错误:x64 Windows程序默认是地址无关代码(PIE),必须使用RIP相对寻址(lea rdx, [msg]),不能用32位绝对寻址(mov rdx, msg),否则会因地址范围超出32位限制触发重定位错误。
  • API调用方式错误:直接call MessageBoxA会生成32位绝对地址引用,必须改为call [__imp_MessageBoxA]通过导入表间接调用,避免截断问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 02:26:11