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

Windows x64调用规范问题:汇编程序执行流程异常求助

x64汇编调用规范问题修复:WriteConsoleA返回异常解决

你的代码在x64 Windows调用约定的栈处理、参数传递上存在多处致命错误,导致程序执行流程被破坏。以下是问题分析和修正方案:

核心错误点

  • 返回地址被非法覆盖:ShowMessageConsole开头的POP指令完全错误。CALL ShowMessageConsole执行后,栈顶是返回地址(8字节),你用POP R10把返回地址弹到了R10,后续RET指令找不到正确的返回地址,必然导致程序崩溃。
  • 未分配影子空间:根据x64 ABI,调用任何Win32 API前,调用者必须在栈上分配32字节的影子空间,供被调用者保存RCX/RDX/R8/R9寄存器。你的代码完全跳过了这一步。
  • 栈未按要求对齐:x64要求调用函数前,RSP必须是16字节对齐(CALL指令会压入8字节返回地址,调用后RSP自动对齐到16字节边界)。你在main中连续push四个值后直接call,此时RSP的对齐状态不符合规范。
  • 参数传递错误:WriteConsoleA的第四个参数是指向DWORD的指针(用于接收实际写入的字符数),你直接传入message_size的数值而非地址;第五个参数需要压栈,但你没有在正确的位置放置它。

修正后的代码

GetStdHandle PROTO
ExitProcess PROTO
WriteConsoleA PROTO

.data
    message         DB "Hello World",0
    bytes_written   DWORD ?  ; 存储实际写入的字符数

.code
    ShowMessageConsole PROC
        ; 调用者已完成参数传递和影子空间分配,直接调用API
        CALL WriteConsoleA
        
        ; 清理栈上的第五个参数(8字节)
        ADD RSP, 8
        RET
    ShowMessageConsole ENDP

    main PROC
        ; 获取标准输出句柄
        MOV RCX, -11           ; STD_OUTPUT_HANDLE常量
        CALL GetStdHandle
        
        ; 分配32字节影子空间 + 预留第五个参数的位置(共40字节)
        ; 确保调用ShowMessageConsole前RSP是16字节对齐
        SUB RSP, 32 + 8
        
        ; 设置WriteConsoleA的参数
        MOV RCX, RAX           ; 1. 控制台句柄
        LEA RDX, message       ; 2. 消息缓冲区地址
        MOV R8, SIZEOF message - 1  ; 3. 要写入的字符数(去掉末尾的0)
        LEA R9, bytes_written  ; 4. 接收实际写入数的指针
        MOV QWORD PTR [RSP + 32], 0  ; 5. 保留参数(NULL),放在影子空间之后
        
        CALL ShowMessageConsole
        
        ; 恢复栈指针到调用前的状态
        ADD RSP, 32 + 8
        
        ; 正常退出程序
        MOV RCX, 0      
        CALL ExitProcess
    main ENDP
END

x64调用规范关键要点

  • 影子空间:调用者必须在栈上分配32字节连续空间,位于栈参数之前。无论被调用者是否使用,这部分空间都必须分配。
  • 栈对齐:调用函数前,RSP必须是16字节对齐。CALL指令压入8字节返回地址后,RSP会自动对齐到16字节边界。
  • 参数传递:前4个参数依次存入RCX/RDX/R8/R9;第5个及以后的参数从右到左压入栈中。
  • 栈清理:调用者负责清理栈上的所有参数(包括超过4个的栈参数和影子空间),通常通过ADD RSP, 字节数恢复栈指针。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 22:05:23