assemblyx86bytebit

I can't find the error in this code. It is x86 assembly


Input: unsigned char vet[] = { 0xBC,0xFF,0x01 };unsigned short int len = 18;
Output: short int minLung;short int maxLung; Given a sequence of bits, determine the minimum and maximum length of subsequences consisting of bits 0.
Input:
An array of bytes (BYTE), which should be considered as a sequence of bits.
A WORD value representing the total number of bits in the sequence.
Output:
Minimum length of zero-bit subsequence.
Maximum length of zero-bit subsequence. (If no such subsequence exists, return -1)

The input value defines the exact length of the sequence in bits. This means that the last byte in the array may be partially used. Bits in each byte must be analyzed from the least significant bit to the most significant bit (from right to left, if you look at the byte).

XOR ESI, ESI       ; current bit index
XOR EDI, EDI       ; zero subsequence length counter

MOV BX, [len]      ; load total bit length into BX
MOV [minLung], BX  ; initialize minLung with maximum possible length

MOV ECX, -1        ; load -1 into ECX to initialize maxLung
MOV [maxLung], CX  ; initialize maxLung with -1

loop_start:
    CMP SI, [len]  ; compare bit index with length
    JGE end_loop   ; if index >= length, jump to end_loop

    MOV EAX, ESI   ; load current bit index into EAX
    MOV EDX, EAX   ; copy current bit index into EDX

    AND EDX, 7     ; bit position within the byte (0...7)
    SHR EAX, 3     ; byte number containing the bit

    MOV AL, [vet + EAX] ; load current byte
    MOV CL, DL          ; CL holds current bit position (0-7)
    SHR AL, CL          ; shift the byte right by bit position
    AND AL, 1           ; isolate the current bit

    CMP AL, 0           ; check if bit == 0
    JNE update_stats    ; if bit == 1, jump to update_stats

    INC EDI             ; increment zero subsequence length
    INC ESI             ; move to next bit
    JMP loop_start      ; continue loop

update_stats:
    CMP EDI, 0          ; check if zero subsequence length is zero
    JE after_update     ; if yes, jump to after_update

    MOV AX, [minLung]   ; load current minimum length into AX
    CMP EDI, EAX        ; compare current length with minLung
    JGE skip_min_update ; if current length >= minLung, skip update
    MOV [minLung], DI   ; update minLung with current length

skip_min_update:
    MOV AX, [maxLung]   ; load current maximum length into AX
    CMP EDI, EAX        ; compare current length with maxLung
    JLE skip_max_update ; if current length <= maxLung, skip update
    MOV [maxLung], DI   ; update maxLung with current length

skip_max_update:
    XOR EDI, EDI       ; reset zero subsequence counter

after_update:
    INC ESI             ; move to next bit
    JMP loop_start      ; continue loop

end_loop:
    CMP EDI, 0          ; check if zero subsequence length is zero
    JE check_result     ; if yes, jump to check_result

    MOV AX, [minLung]   ; load minLung into AX
    CMP DI, AX          ; compare current zero subsequence length with minLung
    JGE skip_end_min    ; if current length >= minLung, skip update
    MOV [minLung], DI   ; update minLung

skip_end_min:
    MOV AX, [maxLung]   ; load maxLung into AX
    CMP DI, AX          ; compare current zero subsequence length with maxLung
    JLE skip_end_max    ; if current length <= maxLung, skip update
    MOV [maxLung], DI   ; update maxLung

skip_end_max:

check_result:
    MOV AX, [maxLung]   ; load maxLung into AX
    CMP AX, -1          ; compare maxLung with -1
    JNE done            ; if not equal, jump to done

    MOV AX, -1          ; if equal, set minLung to -1

done:

I can't find the problem. Please help me


Solution

  • The problem is in the way you initialize maxLung

    MOV ECX, -1        ; load -1 into ECX to initialize maxLung
    MOV [maxLung], CX  ; initialize maxLung with -1
    

    and how you later use it

    MOV AX, [maxLung]   ; load current maximum length into AX
    CMP EDI, EAX        ; compare current length with maxLung
    JLE skip_max_update ; if current length <= maxLung, skip update
    MOV [maxLung], DI   ; update maxLung with current length
    

    The problem is in that CMP EDI, EAX. Had you written this as CMP DI, AX all would have been well.
    Because the word maxLung got initialized at -1 or FFFFh, the value in EAX here is actually 0000FFFFh, and so the relatively very small EDI is always going to be less, which in turns means that maxLung never gets its update!

    You should make a similar change for updating minLung.