首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >x86:以32位数计算从1到0的转换

x86:以32位数计算从1到0的转换
EN

Stack Overflow用户
提问于 2016-05-11 18:12:32
回答 2查看 289关注 0票数 2

我喜欢在32位数中计算1到0的转换数。我发现使用shr从0到1的转换次数是相反的,但我没有得到所需的结果。我该怎么办?

代码语言:javascript
运行
复制
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

而对于4660 (00000000000000000001001000110100),1到0的跃迁数是4。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-11 19:25:13

基本的问题是,您的代码寻找一个0,后面跟着一个1,如果不匹配,它将重新开始。因此,如果它看到00,它就会重新寻找另一个0,如果下一个位是1,它就会重新开始。因此,当过渡被偶数的0所取代时,您就会错过它们。

注意,您还说您需要1到0转换,但您正在寻找0到1转换,但您是从右到左(lsb到msb),因此这可能是正确的,这取决于您想要的位顺序。

显而易见的解决方案是将jnc .loop更改为不重新启动,而是只返回到dec ecx前面的那个,尽管您在那里还需要一个cmp ecx,0; jl .exit

注意,您还可以通过使用由ecx指令设置的Z标志(在eax中的结果为所有0位)来计算位数,从而消除对eax的需求。

加在一起,你会发现:

代码语言:javascript
运行
复制
.loop1: shr eax, 1
        jc .loop1
.loop2: jz .exit
        shr eax, 1
        jnc .loop2
        inc ebx
        jmp .loop1
票数 4
EN

Stack Overflow用户

发布于 2016-05-11 19:27:28

琐事:几个月前,我在尝试实现基于位图的内存管理器的一个方面时考虑过这个问题。

我发现的最有效的解决方案如下(我根据您的示例代码对其进行了调整):

代码语言:javascript
运行
复制
global main               
main:     
    mov eax, [num]    
    ; --- here starts the relevant code ---
    mov ebx, eax         
    shl ebx, 1
    not eax
    and ebx, eax
    popcnt ebx, ebx     ; --- count the changed bits ---
    ; --- continue with your exit routine
.exit:  
    push ebx  
    push    dword msg          
    call    printf             
    add     esp, 8  

注意,计算是在没有循环的情况下完成的。它是纯粹的比特篡改设置位数,最后由POPCNT指令,给出所需的结果。

作为一个应用于给定值4660的例子,该算法的功能如下:

代码语言:javascript
运行
复制
00000000000000000001001000110100 --- MOV EBX, EAX

00000000000000000010010001101000 --- SHL EBX, 1
11111111111111111110110111001011 --- NOT EAX
00000000000000000010010001001000 --- AND EBX, EAX => 'and' the last two lines
=> POPCNT (count the bits of the last line) to get the result of 1 to 0 transitions.
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37170378

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档