64位MASM(ml64.exe)PUSH立即数报A2006错误如何解决
报错原因
触发A2006错误以及无法直接实现64位立即数压栈的原因有两点:
- 语法规则限制:MASM(ml64.exe)要求十六进制立即数如果以A-F范围的字母开头,必须在数值前补前导
0,否则汇编器会将字符串识别为自定义符号而非立即数。你写的FFFF0820CADBA78D以F开头,汇编器查找同名符号失败就会抛出未定义符号错误。 - 硬件指令限制:x86-64指令集不存在编码支持直接压入64位立即数的PUSH操作。就算你补了前导0写成
push 0FFFF0820CADBA78Dh,汇编器依然会报操作数无效错误。x64下PUSH仅支持32位长度的立即数,硬件会自动将32位立即数符号扩展为64位后压栈,仅当目标64位值的高32位全为0或全为F(即符合32位有符号数符号扩展规则)时,才能直接使用PUSH指令加载。
正确实现方式
对于你需要压入的0FFFF0820CADBA78Dh这类不符合32位符号扩展规则的64位立即数,可选择以下两种标准实现:
方案1:寄存器中转(推荐,适配KMDF驱动场景)
选用x64调用约定中定义的易失寄存器(RAX/RCX/RDX/R8-R11,这类寄存器无需额外保存恢复,不会破坏函数上下文),先将立即数加载到寄存器,再执行压栈:
mov rax, 0FFFF0820CADBA78Dh push rax
如果当前逻辑中RAX存了有效数据,换用其他易失寄存器即可。
方案2:直接操作栈(不占用通用寄存器)
如果不想占用通用寄存器,可以手动调整栈顶指针,直接将64位立即数写入栈顶对应内存,效果和PUSH完全一致:
sub rsp, 8 mov qword ptr [rsp], 0FFFF0820CADBA78Dh
注意KMDF驱动开发需要严格遵守x64的16字节栈对齐要求,手动修改RSP后要确保后续栈操作不会破坏对齐,函数返回前必须平衡栈指针。
注意事项
- MASM中所有以A-F开头的十六进制立即数,必须补前导0、结尾加h后缀,否则都会被识别为符号触发A2006错误。
- 不要尝试用两次32位PUSH拼接64位值,x64模式下PUSH操作固定压入8字节数据,两次压栈会多占用8字节栈空间,且值的字节序不符合预期。
内容的提问来源于stack exchange,提问作者JbG
相关产品推荐
相关产品推荐

