2015-09-27 81 views
0

我有一个程序,我正在调用Visual Studio 2010中的x86汇编(MASM)。 它所做的只是将存储在ax寄存器中的基数10数字转换为一个二进制字符串(例如10100b)。我遇到的问题是,只要斧头等于1,它就会覆盖并等于一些大数字。div操作换行(x86汇编)

.code 
main proc 

    xor eax, eax 
    xor ebx, ebx 
    xor ecx, ecx 
    xor edx, edx 

    lea esi, binResult       ; convert result to string (binary notation) 
    mov ax, [result] 
    mov bx, 2 
    call Convert2Bin 


    lea esi, binResult       ; test 
    call PrintString 



    EndofProgram: 

    invoke ExitProcess, 0    
main endp 


Convert2Bin proc      ; Define procedure 
     pushad      ; save registers 
     pushfd      ; save flags 

     divide_Convert2Bin: 

     cmp eax, 1 
     je addOne_ThenExit 

     cmp eax, 0 
     je addZero_ThenExit 

     div ebx 

     cmp edx, 1 
     je addOne_ThenLoop 

     cmp edx, 0 
     je addZero_ThenLoop 

     addOne_ThenLoop: 
     mov byte ptr [esi], '1' 
     inc esi 
     jmp divide_Convert2Bin 

     addZero_ThenLoop: 
     mov byte ptr [esi], '0' 
     inc esi 
     jmp divide_Convert2Bin 

     addOne_ThenExit: 
     mov byte ptr [esi], '1' 
     inc esi 
     jmp done_Convert2Bin 

     addZero_ThenExit: 
     mov byte ptr [esi], '0' 
     inc esi 
     jmp done_Convert2Bin 

     done_Convert2Bin: 
     mov byte ptr [esi], 'b' 

     popfd      ; restore flags 
     popad      ; restore registers 
     ret      ; return to caller 
+0

'pusha/popa'和'和'pushf/popf'都很慢。在asm中写入时,您可以*在每个函数的基础上构建自己的ABI,但是保存/恢复*所有内容*都是不好的选择。标准ABI不保留标志,并且有一些调用者保存的寄存器,可以在不保存的情况下在函数中使用。您只需要保存/恢复ABI指定为被调用者保存的寄存器。 –

回答

1

div ebx需要作为输入一定值EAXEBXEDX并改变EAXEDX。至少你已经忘记的EDX初始化:

... 
pushfd      ; save flags 

mov ebx, 2     ; Divisor 

divide_Convert2Bin: 

cmp eax, 1 
je addOne_ThenExit 

cmp eax, 0 
je addZero_ThenExit 

xor edx, edx    ; Don't forget to initialize EDX 
div ebx 
... 

考虑,你得到的结果(余)在反向订购!

+0

@ lasec0203:由于'div'改变了'EDX',因此您必须每次在'div'之前重复'EDX'的初始化。 – rkhb

+0

我在调试器中检查了EDX。它每次都会被新的余数覆盖。它似乎没有引起EAX包装的问题。 – lasec0203

+0

@ lasec0203:WTF ;-)像我这样做,看看结果! – rkhb