使用奇偶校验位验证对位序列进行错误检查(汇编 x86)

问题描述 投票:0回答:1

给定一个位序列,知道(数据的)每 n 位都有一个奇偶校验位(如果前 n 个中设置为 1 的位数是奇数,则为 1),检查是否有错误。注意: • 以位为单位的长度被指定为输入:可能会发生数组的最后一个字节仅被部分使用的情况。 • 可以假设比特序列的长度始终是(n+1)的倍数。 • 应从最低有效位到最高有效位分析字节内的位。

输入:BYTES 数组(视为位序列), 一个 DWORD(位序列的长度),一个 BYTE(n 的值)。 输出:一个 BYTE(如果有错误则包含 1,否则包含 0)。我尝试写这个,在某些情况下有效,但在其他情况下(例如给定的输入)却不起作用。

#include <stdio.h>

void main() {
    // Input
    unsigned char vet[] = { 0xAD,0xDC };  // Test array
    unsigned int len = 16;  // Length (number of bits)
    unsigned char n = 15;   // Number of data bits

    // Output
    unsigned char errors = 0;  // 1 = errors; 0 = no errors

    __asm {
        XOR ECX, ECX                 // ECX serves as a bit counter
        LEA ESI, vet                 // ESI points to the beginning of the array
        MOV EBX, len                 // EBX contains the length of the bit sequence
        MOV AL, n                    // AL contains the value of n (number of data bits)
        ADD AL, 1                    // Increment AL to include the parity bit
        XOR EDX, EDX                 // EDX will be used for counting bits set to 1

        check_next_bit:
        CMP ECX, EBX                 // Compare the counter with the sequence length
        JGE done_checking            // If the counter is greater or equal, finish

        MOV EDI, ECX                 // EDI is the current index
        SHR EDI, 3                   // Divide by 8 to find the correct byte
        MOVZX EAX, BYTE PTR[ESI + EDI] // Load the current byte into EAX

        MOV EDI, ECX
        AND EDI, 7                   // Get the position of the bit within the byte
        SHR EAX, CL                  // Shift right to get the required bit
        AND EAX, 1                   // Isolate the least significant bit

        CMP CL, n                    // Compare the counter with n (number of data bits)
        JE check_parity              // If equal, check the parity

        ADD EDX, EAX                 // Add the current bit to EDX
        INC CL                       // Increment the bit counter
        JMP check_next_bit           // Repeat the cycle for the next bit

        check_parity:
        AND EDX, 1                   // Calculate the parity
        CMP EDX, EAX                 // Compare the calculated parity with the expected parity bit
        JNE set_error                // If they don't match, set the error flag

        XOR EDX, EDX                 // Reset the count of bits set to 1
        INC CL                       // Increment the bit counter
        JMP check_next_bit           // Repeat the cycle for the next bit

        set_error:
        MOV errors, 1                // Set the error flag
        JMP done_checking            // Finish the checking

        done_checking:
    }

    // Output to screen
    printf("The bit sequence %scontains errors\n", (errors ? "" : "does not "));
}

我注意到汇编代码没有正确处理奇偶校验位。它应该检查奇偶校验位是否与前面位的奇偶校验计算相匹配,但似乎当前的实现没有按预期工作。

c algorithm assembly x86
1个回答
0
投票

对于此类任务,您需要开发一个可以独立于其余代码运行的输入代码。下面的“位获取器”使用自己的一组寄存器 EAX、ESI 和 EDI,并通过进位标志输出单个位。

 xor   ebx, ebx
 xor   esi, esi     ; Offset within the source array
 xor   edi, edi     ; Counts number of cached (in AL) source bits

 mov   ecx, len     ; ECX is outer loop counter (len) using step (n + 1)
OuterLoop:
 mov   bl, n
 inc   ebx          ; EBX is inner loop counter (n + 1) using step (1)
 sub   ecx, ebx     ; Outer loop step is taken early
 xor   edx, edx     ; Counts number of ON bits
InnerLoop:

 test  edi, edi                  ; 'bit fetcher'     \
 jnz   GetOneBit                                      | This code operates
 add   edi, 8                                         | asynchronous to
 movzx eax, byte ptr [vet + esi] ; Read one byte      | the loops around it
 inc   esi                       ; and cache it in AL |
GetOneBit:                                            | It would be nice to keep
 dec   edi                       ; Consume one bit    | this in a subroutine
 shr   eax, 1                    ; from AL -> CF     /

 adc   edx, 0
 dec   ebx
 jnz   InnerLoop
 and   edx, 1       ; If bit 0 is ON, then there's a mismatch between
 jnz   Done         ; Error EDX=1     calculated and stored parity bit
 test  ecx, ecx     ; (*)
 jnz   OuterLoop
Done:
 mov   errors, dl   ; DL=[0,1]

(*) 鉴于任务描述表明,无需查找不完整的记录; “可以假设比特序列的长度总是(n+1)的倍数。”

© www.soinside.com 2019 - 2024. All rights reserved.