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

x64 MASM程序调用Windows API输出字符串无结果求助

问题排查与修复方案

你这段代码有几个关键问题,导致控制台无输出:

核心问题分析

1. 变量类型不匹配(最关键)

WriteConsoleA的第四个参数要求是指向32位整数的指针,但你定义的message_size是DW(16位字类型)。当API尝试往这个地址写入4字节的实际输出长度时,会越界覆盖栈内其他数据,直接导致调用失败或后续执行异常。

2. 缺少API调用错误检查

你没检查GetStdHandle的返回值——如果获取标准输出句柄失败(比如环境异常),后续调用WriteConsoleA肯定不会有输出。

补充:栈对齐细节

x64 Windows要求调用API前栈必须是16字节对齐。你代码里SUB RSP, 5*8其实刚好满足(进入main时RSP是8字节对齐,减40后变为16的倍数),所以这个不是核心问题,但给栈分配代码加注释会更便于维护。


修复后的代码

GetStdHandle PROTO
ExitProcess PROTO
WriteConsoleA PROTO

.data
    message         DB "Hello World",0
    message_size    DWORD ?  ; 改为32位DWORD,匹配API要求的参数类型

.code
    main PROC
        ; 分配32字节阴影空间 + 8字节栈参数 = 40字节,保证16字节对齐
        SUB RSP, 40  
        
        ; 获取标准输出句柄
        MOV RCX, -11           
        CALL GetStdHandle
        ; 检查句柄是否无效(INVALID_HANDLE_VALUE = -1)
        CMP RAX, -1
        JE ExitProg  ; 句柄无效直接退出
        
        ; 调用WriteConsoleA输出字符串
        MOV RCX, RAX           ; 参数1:标准输出句柄
        LEA RDX, message       ; 参数2:要输出的字符串指针
        MOV R8, SIZEOF message - 1  ; 参数3:输出字节数(去掉末尾的空字符)
        LEA R9, message_size   ; 参数4:接收实际输出长度的指针
        MOV QWORD PTR [RSP + 32], 0 ; 参数5:预留参数,设为NULL
        CALL WriteConsoleA
        
ExitProg:
        MOV RCX, 0      
        CALL ExitProcess
    main ENDP
END

修复点说明

  • 修正变量类型:把message_size从DW改成DWORD,彻底解决内存越界问题,保证API能正常写入输出长度。
  • 增加错误检查:添加句柄有效性判断,避免因无效句柄导致的无输出情况。
  • 明确栈空间注释:给栈分配代码添加注释,清晰说明分配的空间用途,后续维护更方便。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 10:01:16