x86:计数以32位数字从1转换为0 [英] x86: Count transitions from 1 to 0 in 32 bit number
问题描述
我喜欢以32位数字计算从1到0的过渡数.我发现使用shr
以相反的顺序从0过渡到1的次数,但没有得到所需的结果.我该怎么办?
I like to count the number of 1 to 0 transition in a 32 bit number. I found that the number of transitions from 0 to 1 in reverse order using shr
, but I don't get the required result. What should I do?
extern printf
SECTION .data
msg: db "The number of transitions are : %d",10,0
inta1: dd 1234567 ; integer 1234567
num: dd 4660
SECTION .text
global main
main:
mov eax, [num]
mov ecx,32
mov ebx,0
.loop: dec ecx
cmp ecx,0
jl .exit
shr eax,1
jc .loop
dec ecx
shr eax, 1
jnc .loop
inc ebx
jmp .loop
.exit:
push ebx
push dword msg
call printf
add esp, 8
输出:
过渡数量为:2
The number of transitions are : 2
而对于4660(00000000000000000001001000110100
),从1到0的转换数是4.
whereas for 4660 (00000000000000000001001000110100
) the number of 1 to 0 transitions are 4.
推荐答案
基本问题是您的代码将查找0
后跟1
,如果不匹配,则会重新开始.因此,如果看到00
,它将重新开始寻找另一个0
;如果下一位是1
,它将重新开始.因此,当过渡出现偶数0
s
The basic problem is that your code looks for a 0
followed by a 1
and if it doesn't match, it starts over again. So if it sees 00
it starts over looking for another 0
and if the next bit is 1
it starts over. So you miss transitions when they are preceeded by an even number of 0
s
请注意,您还说要从1到0的过渡,但是要从0到1的过渡,但是从右到左(从lsb到msb),可能是正确的,具体取决于您想要的位顺序.
Note also you say you want 1-to-0 transitions, but you're looking for 0-to-1 transitions, BUT you are looking right to left (lsb to msb) so that may be correct, depending on which bit order you want.
显而易见的解决方案是将jnc .loop
更改为不重新开始,而只返回到紧接的前一个dec ecx
,尽管那里也需要cmp ecx,0; jl .exit
.
The obvious solution is to change the jnc .loop
to not start over, but only go back to the immediately preceeding dec ecx
, though you also need a cmp ecx,0; jl .exit
there.
请注意,当结果(在eax
中)全部为0时,您可以使用shr
指令设置的Z
标志来摆脱对ecx
的需要,并计数位数.位.
Note also you could get rid of the need of ecx
and counting the number of bits by using the Z
flag which is set by the shr
instruction when the result (in eax
) is all 0 bits.
在一起,您会得到类似的东西
Taken together, that gives you something like:
.loop1: shr eax, 1
jc .loop1
.loop2: jz .exit
shr eax, 1
jnc .loop2
inc ebx
jmp .loop1
这篇关于x86:计数以32位数字从1转换为0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!