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

如何匹配MOV读两字节后接AND指令的x86原汇编代码?

旧VC++编译游戏反汇编匹配问题解决方法

我正在反编译一款用Microsoft Visual C++ 4.1/4.2编译的Windows 95旧游戏可执行文件,在decomp.me上为每个函数创建scratch,目标是写出能精准匹配原汇编的C代码(注意decomp.me采用AT&T汇编语法)。

遇到的核心问题:
原汇编通过先读取两字节数据,再用AND指令清零高位,实现从四字节结构/联合体中读取unsigned short:

mov 0x4328f8(,%eax,2),%ax
and $0xffff,%eax

但尝试常规写法时,生成的汇编始终不匹配:

  • 直接用unsigned short类型读取并赋值给unsigned int,编译器会生成带xor的指令且无and:

    xor %edx,%edx
    mov _DAT_004328f8-0x10(,%eax,2),%dx

  • 用有符号short类型,mov会变成movswl,手动加& 0xFFFF也无法生成预期的and指令:

    movswl _DAT_004328f8-0x10(,%eax,2),%eax

可行的解决思路

  1. 切换低优化级别
    在decomp.me的编译器设置中选择-O0(无优化)。旧版VC++4.x优化程度低,不会使用movzx这类现代扩展指令,而无优化的GCC编译行为更接近旧编译器,会生成先读16位寄存器再清零高位的代码。

  2. 拆分赋值操作
    不要将读取和类型转换合并成一行,拆分为两步明确的赋值,引导编译器生成匹配的汇编:

    // 定义数据指针,对应原汇编的0x4328f8地址
    unsigned short *game_data = (unsigned short *)0x4328f8;
    // 假设eax是传入的索引值
    unsigned int index = eax;
    
    // 第一步:读取16位值到临时变量
    unsigned short temp = game_data[index];
    // 第二步:转换为32位无符号整数
    unsigned int result = temp;
    
  3. 强制阻止优化(可选)
    如果低优化级别仍被编译器优化掉and指令,给临时变量添加volatile修饰,强制编译器保留中间读取步骤:

    volatile unsigned short temp = game_data[index];
    unsigned int result = temp;
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 20:38:23