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

基于奇偶位校验的位序列错误检测(x86汇编)问题排查

修复奇偶校验位序列检测的x86汇编+C代码问题

问题背景

我们需要实现一个位序列奇偶校验检测功能:每n个数据位后跟随1个奇校验位(前n位中1的个数为奇数时,校验位为1),输入为BYTE数组、位序列长度(恒为n+1的倍数)、n值,输出1表示存在错误,0表示无错误。现有混合x86汇编的C代码在测试案例(输入数组0xAD、0xDC,位长16,n=15)中无法正确运行,核心问题是奇偶位处理逻辑错误,未匹配前序数据位的奇偶计算结果。

常见错误根源

  • 位顺序遍历错误:未严格按照BYTE内从最低有效位(LSB,第0位)到最高有效位(MSB,第7位)的顺序遍历,导致位序列完全错乱
  • 校验位与数据位混淆:处理时误将校验位计入数据位的1的个数统计,或者提前读取校验位导致逻辑错位
  • 奇校验逻辑错误:错误判断预期校验位的值(比如搞反奇偶对应的校验位取值)
  • 边界位处理失误:最后一个BYTE仅使用部分位时,未精准停止遍历,导致多算无关位

修复后的代码

#include <stdint.h>

typedef unsigned char BYTE;
typedef unsigned int DWORD;

BYTE check_parity_error(const BYTE* data, DWORD bit_length, BYTE n) {
    DWORD total_groups = bit_length / (n + 1);
    BYTE error = 0;

    __asm {
        mov esi, data          ; ESI指向输入BYTE数组
        mov ecx, total_groups  ; ECX存储需要处理的校验组数
        xor edx, edx           ; EDX跟踪当前处理的全局位索引
        xor ebx, ebx           ; EBX存储当前组内数据位的1的计数

        group_start:
            cmp ecx, 0
            je check_end       ; 所有组处理完成,退出
            dec ecx

            ; 重置当前组的1计数,准备处理n个数据位
            mov bl, 0
            mov eax, n         ; EAX存储当前组需要处理的数据位数量

        data_bit_process:
            cmp eax, 0
            je parity_check    ; 数据位处理完毕,开始校验位检查
            dec eax

            ; 计算当前位所在的字节索引和字节内位偏移
            mov edi, edx
            shr edi, 3         ; 字节索引 = 全局位索引 / 8
            mov cl, dl
            and cl, 7          ; 字节内位偏移 = 全局位索引 % 8

            ; 提取当前位的值
            mov al, [esi + edi]
            shr al, cl
            and al, 1

            ; 更新1的计数
            add bl, al

            inc edx            ; 全局位索引+1,处理下一个数据位
            jmp data_bit_process

        parity_check:
            ; 提取当前组的校验位
            mov edi, edx
            shr edi, 3
            mov cl, dl
            and cl, 7

            mov al, [esi + edi]
            shr al, cl
            and al, 1          ; AL存储实际校验位的值

            ; 计算预期校验位:奇校验,数据位1的个数为奇数则预期1,否则0
            test bl, 1
            mov ah, 1          ; 默认预期为1(奇数个1)
            jnz expected_match
            mov ah, 0          ; 偶数个1,预期校验位为0
        expected_match:

            ; 对比实际与预期校验位
            cmp al, ah
            je parity_ok       ; 校验通过,处理下一组
            mov error, 1       ; 校验失败,标记错误并退出
            jmp check_end

        parity_ok:
            inc edx            ; 跳过校验位,进入下一组
            jmp group_start

        check_end:
    }

    return error;
}

修复关键点说明

  • 严格按LSB→MSB遍历:通过全局位索引 % 8获取字节内的位偏移,shr al, cl精准提取对应位,确保位序列顺序完全符合要求
  • 分离数据位与校验位处理:先完整处理每组的n个数据位并统计1的个数,再单独提取校验位进行对比,避免逻辑混淆
  • 准确的奇校验逻辑:通过test bl, 1判断数据位1的个数的奇偶性,生成对应的预期校验位值,确保和规则完全匹配
  • 精准位跟踪:用全局位索引edx逐位推进,即使最后一个BYTE仅使用部分位,也能准确停止遍历,不会处理无关位

故障案例测试验证

针对测试输入BYTE数组[0xAD, 0xDC]、位长16、n=15:

  1. 总组数为16/(15+1)=1,即15个数据位+1个校验位
  2. 从LSB开始的15个数据位依次为:0xAD的第0-7位(1,0,1,1,0,1,0,1)、0xDC的第0-6位(0,0,1,1,1,0,1)
  3. 统计1的个数:共10个(偶数),预期校验位为0
  4. 实际校验位是0xDC的第7位(二进制11011100的最高位为1),与预期不符,代码返回1(错误),符合预期逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 16:30:02