MASM除法溢出

11

我正在尝试在汇编语言中将两个数字相除。我正在使用《Intel计算机的Irvine汇编书》并且无论如何都不能让除法正常工作。

以下是我的代码:

.code
main PROC
    call division
    exit
main ENDP

division PROC
    mov eax, 4
    mov ebx, 2
    div ebx
    call WriteDec
    ret
divison ENDP

END main

WriteDec应该写入eax寄存器中的任何数字(在除法调用后应设置为商)。但每次运行它时,Visual Studio都会崩溃(但程序确实编译成功)。


1
你能在Visual Studio调试器中逐步执行它吗?如果你逐步执行每个指令,你能走多远? - Greg Hewgill
@GregHewgill 你如何使用Visual Studio调试器逐步执行每个汇编指令?即使经过几次谷歌搜索,我仍然没有弄清楚这一点。 - Anderson Green
1
@AndersonGreen:他们不断更改菜单项的名称和快捷键。寻找类似“查看反汇编”的东西。有一个包含寄存器窗口、内存窗口、堆栈查看器、反汇编等视图。对于VS 2012,以下是说明:http://msdn.microsoft.com/en-us/library/a3cwf295.aspx - Greg Hewgill
@GregHewgill,VS 2010有相应的指令吗? - Anderson Green
@AndersonGreen: 当然可以,参见 https://www.google.com/search?q=vs+2010+disassembly - Greg Hewgill
显示剩余2条评论
3个回答

17

在进行除法运算之前,您需要将EDX寄存器零扩展:

mov eax, 4
mov ebx, 2
xor edx, edx          ;set edx to zero
div ebx
call WriteDec

;set edx to zero是MASM中的一个注释。我不知道在使用C内联汇编时是否有效,所以如果你正在使用它,请不要复制它 :)


2
不需要显式地将EDX清零,通常可以使用CDQ指令将EAX符号扩展为EDX。如果EAX是非负数,则EDX填充为零;如果EAX为负数,则EDX填充为全1位。 - I. J. Kennedy
是的,在这方面你是正确的,但是 OP 执行的是无符号除法,所以我保持我的答案简单。 - slugster

4

是的,你需要将edx设置为零。

最简单的方法是:

xor edx, edx

0
我觉得上面提到的原因是正确的,因为当您将eax除以ebx时,两个都是32位数字,但被除数需要是64位,而除数是32位,所以它将edx视为msb...您可以使edx为0,或者使用bx而不是3bx。这样,您将会用16位数字除以32位数字。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接