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

为何我实现的MASM32 32位校验和宏的Dart版本运行结果不正确?

问题分析与修复方案

原始MASM32校验和逻辑拆解

原始宏的运算规则整理如下:

  • 输入为字节流、字节长度,返回32位无符号整数校验和
  • 初始化校验值为0,若输入长度小于4直接返回0
  • 每次从输入流读取4字节小端序(x86默认)双字(DWORD)参与运算:
    1. 校验值 += 当前双字,结果按32位无符号截断
    2. 当前双字左移1位,移出的最高位作为进位,通过adc指令把进位+1加到左移后的结果上
    3. 校验值异或上一步得到的变换结果,按32位无符号截断
  • 若最终剩余不足4字节,将输入指针回退到「总长度-4」的位置,凑够4字节再执行一次上述运算后结束

现有代码核心错误

  1. 字节序完全错误:x86读取4字节双字是小端序,你写的fusion函数按输入顺序从左到右拼接16进制字符串,得到的是大端序数值,和汇编逻辑完全相反
  2. 进位计算逻辑错误:adc ebx,1的进位是双字左移1位时移出的第31位,不是你理解的单字节最高位,转字符串取首位的逻辑完全不对
  3. 循环条件错误:while(i < src.length-4)会跳过长度恰好为4的输入的唯一一次循环,直接返回0
  4. 无32位截断处理:Dart的int默认是64位,所有位运算、加减运算后没有做32位无符号截断,结果会溢出预期范围
  5. 剩余字节处理缺失:没有实现汇编中不足4字节时凑4字节重算最后一次的逻辑

修复后的正确实现

import 'dart:convert';
import 'dart:io';

int checksum32(List<int> bytes) {
  int len = bytes.length;
  int checksum = 0;
  if (len < 4) return checksum & 0xFFFFFFFF;
  
  int i = 0;
  while (true) {
    // 取4字节小端序拼DWORD
    int dword = bytes[i] | (bytes[i+1] << 8) | (bytes[i+2] << 16) | (bytes[i+3] << 24);
    dword &= 0xFFFFFFFF;
    
    // 对应汇编 add eax, ebx
    checksum = (checksum + dword) & 0xFFFFFFFF;
    
    // 对应shl ebx,1 + adc ebx,1
    int carry = (dword >> 31) & 1;
    int transform = ((dword << 1) & 0xFFFFFFFF) + carry + 1;
    transform &= 0xFFFFFFFF;
    
    // 对应xor eax, ebx
    checksum = (checksum ^ transform) & 0xFFFFFFFF;
    
    i += 4;
    if (i >= len) break;
    // 剩余不足4字节,调整i到len-4,最后跑一次
    if (len - i < 4) {
      i = len - 4;
    }
  }
  
  return checksum & 0xFFFFFFFF;
}

// 调用示例
void main() {
  String input = File("你的文件路径").readAsStringSync();
  // 字符串转字节流,注意和汇编输入的编码一致,汇编如果是ASCII就用ascii.encode,是utf8就用utf8.encode
  List<int> bytes = utf8.encode(input);
  print(checksum32(bytes));
}

注意事项

  • 输入字节流的编码要和汇编场景完全一致,汇编如果处理的是GBK等其他编码的字符串,Dart侧也要转成对应编码的字节流再计算,否则结果必然不一致
  • 如果你的场景确定输入长度永远是4的倍数,可以删除剩余字节处理的分支,进一步简化代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 15:36:04