如何用SHR和SHL指令统计AX寄存器中置位比特数并存入BX?
用SHR/SHL指令统计AX寄存器中置位比特数到BX
核心思路是通过循环移位把AX的每一位逐位移入进位标志(CF),然后根据CF的值累计计数到BX。以下是两种基于SHR和SHL的实现方案:
方案1:使用SHR(右移)统计最低位
右移指令SHR AX,1会把AX的最低位移入CF,我们可以利用这个特性逐位检查:
; 初始化BX为0(统计计数器) XOR BX, BX ; 设置循环次数:AX是16位寄存器,需要处理16次 MOV CX, 16 count_loop: SHR AX, 1 ; AX右移1位,最低位进入CF ADC BX, 0 ; 将CF的值加到BX(CF=1则BX+1,否则BX不变) LOOP count_loop ; CX减1,不为0则继续循环
关键说明:
XOR BX,BX是高效的寄存器清零方式,比MOV BX,0占用更少字节ADC BX,0等价于:如果CF=1则INC BX,否则无操作,用这条指令可以简化判断逻辑- 循环结束后,BX中就是AX中置位比特的总数
方案2:使用SHL(左移)统计最高位
左移指令SHL AX,1会把AX的最高位移入CF,实现逻辑和右移完全一致,只是移位方向相反:
XOR BX, BX MOV CX, 16 count_loop_shl: SHL AX, 1 ; AX左移1位,最高位进入CF ADC BX, 0 LOOP count_loop_shl
保留AX原始值的处理
如果需要保留AX的原始数据,先把AX备份到其他寄存器(比如DX)再操作:
MOV DX, AX ; 备份AX到DX XOR BX, BX MOV CX, 16 count_loop_save: SHR DX, 1 ADC BX, 0 LOOP count_loop_save ; 此时AX仍为原始值,BX为置位比特数
常见问题排查
如果你之前尝试SHR/SHL效果不佳,大概率是以下原因:
- 未初始化BX:BX初始值非0会导致统计结果错误
- 循环次数错误:AX是16位,必须循环16次才能覆盖所有位
- 未利用CF标志:直接移位后没检查CF,漏掉了计数逻辑
内容的提问来源于stack exchange,提问作者SkyBear
相关产品推荐
相关产品推荐

