汇编中位反转数检测方法及SHL指令CF标志异常排查
8086汇编位反转检测代码问题排查
核心问题分析
你的代码运行异常、SHL指令CF标志不符合预期,主要由以下关键错误导致:
1. 直接修改原数组数据,破坏检测基准
代码中直接对ARR1和ARR2的内存单元执行SHR/SHL操作,每次移位都会改变数组原始值。比如第一个元素初始为1000000000000001b,第一次SHR后变成0100000000000000b,后续循环检测的是被修改过的数据,完全偏离了"对比原始数组元素位反转"的逻辑,CF标志自然无法符合预期。
2. 数组元素索引计算错误
ARR1和ARR2是dw(双字节)类型数组,但代码中用[si+bx]和[di+bx]访问元素:
- bx的计算逻辑是
bx = k - cx,k为元素个数(2),第一次循环bx=0,对应第一个元素;第二次cx=1,bx=1。 - 但
dw元素每个占2字节,偏移1字节会访问到第一个元素的低字节和第二个元素的高字节,属于越界访问,移位的对象根本不是目标数组元素,CF标志的变化当然不符合预期。
3. 冗余的CLC指令干扰逻辑
你在SHL前执行CLC,但SHL指令本身会根据移出的位覆盖CF值,这步操作完全多余,还会混淆对CF标志的判断逻辑。
修复方案
针对上述问题,修正后的核心逻辑如下:
- 先将数组元素加载到寄存器再移位,保留原数组的原始值
- 修正索引计算,用
bx*2作为偏移量(适配dw类型的双字节元素) - 移除冗余的
CLC指令
修复后的完整代码
IDEAL MODEL small STACK 100h DATASEG k dw 2 ; 数组长度 ARR1 dw 2 dup (?) ARR2 dw 2 dup (?) CODESEG start: mov ax,@data mov ds,ax lea si,[ARR1] lea di,[ARR2] mov cx,k ; cx = 数组元素个数 xor dx,dx ; dx 用于统计符合条件的对数 ; 初始化测试数据 mov [ARR1],1000000000000001b mov [ARR2],1000000000000001b ; 该元素的位反转就是自身,符合条件 mov [ARR1+2],0033h ; 第二个元素,0033h的二进制是0000000000110011 mov [ARR2+2],0C000h ; 0033h的位反转是1100000000000000,即0C000h L1: ; 遍历数组每个索引 mov bx,k sub bx,cx push cx mov cx,16 ; 每个元素16位,循环16次 mov ax, [si+bx*2] ; 加载当前ARR1元素到ax(不修改原数组) mov bp, [di+bx*2] ; 加载当前ARR2元素到bp(不修改原数组) mov dx,dx ; 重置临时位标志 L2: ; 逐位对比 xor dx,dx shr ax,1 jnc nc1 inc dl ; ARR1当前位为1,标记dl=1 nc1: shl bp,1 jnc nc2 inc dh ; ARR2当前位为1,标记dh=1 nc2: cmp dl,dh jne end_loop2 ; 位不相等,说明不是位反转,跳出当前元素检测 dec cx jnz L2 inc dx ; 16位全部匹配,符合条件,计数+1 end_loop2: pop cx dec cx jnz L1 exit: mov ax, 4c00h int 21h END start
内容的提问来源于stack exchange,提问作者yahel amity
相关产品推荐
相关产品推荐

