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

64位MASM中sscanf在Win10/11返回0问题排查求助

MASM64 SDK中sscanf返回0问题的排查与解决

问题现象

  • 调用sscanf的代码在Windows 7运行正常,Windows 10/11下返回0;
  • 代码在原项目中可正常运行,迁移到新项目后sscanf返回0;
  • 原本正常的代码运行一段时间后,也出现sscanf返回0的情况。

核心排查与修复方案

1. 64位Windows栈对齐要求未满足

64位Windows调用约定强制要求调用函数前栈必须是16字节对齐。你的第一段代码中sub rsp, 30h(分配48字节栈空间),加上push rbp的8字节,栈指针偏移量为56字节,并非16的整数倍。这种未对齐的栈在Windows 7中可能兼容,但Windows 10/11的严格栈检查会导致sscanf调用失败。

修复:调整栈空间为16的倍数,例如将sub rsp, 30h改为sub rsp, 38h(分配56字节,加上rbp的8字节总偏移64,为16*4),确保调用sscanf前rsp符合对齐要求。

2. MASM64 SDK invoke宏的参数处理问题

第三方invoke宏可能存在参数传递或栈处理的bug,比如未正确维护寄存器参数、未自动处理栈对齐。

验证与修复:暂时替换invoke为手动call调用,测试是否正常:

mov rcx, offset buffer
mov rdx, offset fmt1
mov r8, offset temp
call sscanf

如果手动call正常,说明invoke宏存在问题,需检查宏定义,或直接改用手动调用方式。

3. 字符串终止符缺失或内存污染

  • 第二段代码中GetDlgItemTextA获取的字符串可能因长度超限导致0终止符丢失,sscanf无法识别有效格式;
  • 数据段变量(如buffer、temp)可能被意外覆盖,导致解析失败。

修复:

  • 在GetDlgItemTextA后手动添加0终止符:
lea r8, buffer
invoke GetDlgItemTextA,,ID_TXT1,,size_of_buffer
or eax,eax
jz wmBYE
mov byte ptr [r8+eax], 0 ; 强制添加字符串终止符
  • 检查数据段变量布局,避免地址重叠或未初始化的内存污染。

4. 运行时库与Locale差异

Windows 10/11的msvcrt.dll版本与Win7不同,sscanf的浮点数解析可能受系统Locale影响(比如部分Locale用逗号作为小数点分隔符)。

修复:显式设置C Locale,避免解析行为变化:

invoke setlocale, LC_ALL, offset locale_c
.data
locale_c db "C", 0

5. 栈帧未正确恢复导致内存泄漏

第一段代码中建立栈帧后,返回前未恢复rsp到rbp,直接ret会导致栈空间泄漏,长期运行后栈资源耗尽,引发后续调用失败。

修复:返回前恢复栈帧:

mov rsp, rbp
pop rbp
ret

修复后的第一段代码示例

.code
main proc
    push rbp
    mov rbp, rsp
    sub rsp, 38h ; 保证16字节对齐的栈空间
    mov rcx, offset buffer
    mov rdx, offset fmt1
    mov r8, offset temp
    invoke sscanf
    movq xmm0, temp
    mov rsp, rbp ; 恢复栈帧
    pop rbp
    ret
main endp

.data
fmt1 db "%lf", 0
temp dq ?
buffer db "3.14159264", 0
end

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 23:10:54