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

x86汇编代码调试求助:零比特子序列长度计算问题

汇编代码错误排查:全0子序列最小/最大长度计算

需求说明

给定比特序列,需计算其中全0子序列的最小和最大长度:

  • 输入:字节数组(BYTE)、表示总比特数的WORD值
  • 分析规则:从每个字节的**最低有效位(LSB)到最高有效位(MSB)**处理,最后一个字节可仅使用部分比特
  • 输出:short int类型的minLung(最小长度)和maxLung(最大长度);无全0子序列时,两者均返回-1
  • 输入示例:
unsigned char vet[] = { 0xBC,0xFF,0x01 };
unsigned short int len = 18;

原代码中的错误点

1. 无全0子序列时,minLung未正确设为-1

在check_result段中,当检测到maxLung仍为初始值-1(即无全0子序列)时,代码仅将AX设为-1,但未将该值写入minLung,导致minLung保留初始的总比特数,不符合需求。

2. 32位与16位寄存器混合比较导致符号错误

maxLung是16位short int,初始值为-1(二进制0xFFFF)。在更新maxLung时,代码使用32位寄存器EDI(计数器)与16位寄存器AX(加载maxLung)比较:

MOV AX, [maxLung]   ; AX = 0xFFFF(即-1,16位)
CMP EDI, EAX        ; EAX会被零扩展为32位的0x0000FFFF,而非符号扩展为0xFFFFFFFF

此时,任何正的全0子序列长度(EDI为正的32位值)都会被判定为小于等于0x0000FFFF,导致maxLung无法被正确更新。

3. 寄存器使用冗余且易引发类型混淆

全程使用32位寄存器EDI作为计数器,但总比特数是16位WORD,计数器最大值不会超过16位范围,使用16位寄存器DI即可,避免32位与16位混合操作的错误。

修正后的汇编代码

XOR SI, SI        ; current bit index(16位足够,匹配len的WORD类型)
XOR DI, DI        ; zero subsequence length counter(16位)

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

MOV CX, -1        ; load -1 into CX(16位,匹配maxLung的short类型)
MOV [maxLung], CX ; initialize maxLung with -1

loop_start:
    CMP SI, [len] ; compare bit index with length(均为16位,无类型问题)
    JGE end_loop  ; if index >= length, jump to end_loop

    MOV AX, SI    ; load current bit index into AX(16位)
    MOV DX, AX    ; copy current bit index into DX

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

    MOV AL, [vet + AX] ; load current byte
    MOV CL, DL         ; CL holds current bit position (0-7)
    SHR AL, CL         ; shift to get the target bit
    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 DI             ; increment zero counter
    INC SI             ; move to next bit
    JMP loop_start

update_stats:
    CMP DI, 0          ; check if no zero subsequence before this 1
    JE after_update

    ; Update minLung
    MOV AX, [minLung]
    CMP DI, AX
    JGE skip_min_update
    MOV [minLung], DI

skip_min_update:
    ; Update maxLung(全程用16位寄存器,避免符号扩展错误)
    MOV AX, [maxLung]
    CMP DI, AX
    JLE skip_max_update
    MOV [maxLung], DI

skip_max_update:
    XOR DI, DI       ; reset zero counter

after_update:
    INC SI
    JMP loop_start

end_loop:
    CMP DI, 0          ; check if there's an unfinished zero subsequence
    JE check_result

    ; Update minLung for the last zero subsequence
    MOV AX, [minLung]
    CMP DI, AX
    JGE skip_end_min
    MOV [minLung], DI

skip_end_min:
    ; Update maxLung for the last zero subsequence
    MOV AX, [maxLung]
    CMP DI, AX
    JLE skip_end_max
    MOV [maxLung], DI

skip_end_max:

check_result:
    MOV AX, [maxLung]
    CMP AX, -1
    JNE done

    ; No zero subsequences, set both to -1
    MOV AX, -1
    MOV [minLung], AX
    MOV [maxLung], AX

done:

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 00:24:54