汇编代码问题:按popcount奇偶性移位未生效,求修复方案
问题描述
需求:编写汇编代码检查变量的popcount(置位位数)是奇数还是偶数,若位数为偶数则将变量右移对应位数,若为奇数则左移对应位数。
以下是测试代码:
IDEAL MODEL small STACK 100h DATASEG TAV db 00001001b t_copy db 00001001b CODESEG start: xor cx,cx mov cx,8 xor al,al L1: shr [t_copy],1 jnc nc inc al nc: dec cx jnz L1 mov cl,al and al,00000001h cmp al,0h jz even_ jnz odd odd: shl [TAV],cl jmp exit even_: shr [TAV],cl exit: mov ax, 4c00h int 21h END start
运行后变量TAV的值未发生移位变化,推测是误将变量值当作内存索引操作,寻求修复方案。
修复方案
问题核心在于8086汇编中,直接对内存操作数执行移位指令时,必须显式指定操作数的大小,否则汇编器会默认按16位处理(MODEL small下的默认寻址宽度),但你的变量是字节类型(db),导致寻址错误,移位操作没有作用到目标变量上。
更高效且不易出错的做法是先把内存变量加载到寄存器中操作,完成后再写回内存。修复后的代码如下:
IDEAL MODEL small STACK 100h DATASEG TAV db 00001001b t_copy db 00001001b CODESEG start: xor cx,cx mov cx,8 xor al,al mov bl, [t_copy] ; 将t_copy加载到bl寄存器 L1: shr bl,1 ; 对寄存器移位,避免内存寻址歧义 jnc nc inc al nc: dec cx jnz L1 mov cl,al and al,00000001h cmp al,0h jz even_ jnz odd odd: mov bl, [TAV] ; 加载TAV到寄存器 shl bl,cl ; 寄存器移位 mov [TAV], bl ; 写回内存 jmp exit even_: mov bl, [TAV] shr bl,cl mov [TAV], bl exit: mov ax, 4c00h int 21h END start
关键修改点
- 计算popcount时:将
t_copy的值加载到bl寄存器,对寄存器执行移位操作,避免直接操作内存带来的寻址歧义。 - 移位
TAV时:同样先把TAV加载到寄存器,完成移位后再写回内存,确保操作的是变量的值而非错误的内存地址。
如果坚持要直接操作内存,也可以通过显式指定操作数大小来修复,比如把shr [t_copy],1改为shr byte ptr [t_copy],1,移位TAV时改为shl byte ptr [TAV],cl,但寄存器操作的效率更高,也更符合汇编的常规写法。
内容的提问来源于stack exchange,提问作者yahel amity
相关产品推荐
相关产品推荐

