Assembly 8086汇编:在不使用mul指令的情况下,将两个16位数字相乘以产生32位结果

Assembly 8086汇编:在不使用mul指令的情况下,将两个16位数字相乘以产生32位结果,assembly,masm,x86-16,Assembly,Masm,X86 16,为了理解使用x86汇编语言的好处,我尝试编写一个16x16位乘法例程作为练习,它接受两个无符号的16位值,并使用移位和*addin*g将它们相乘,最后的32位结果存储在DX:AX中 运行代码没有问题(换句话说,它编译得很好,并与我的链接程序一起运行),但是代码没有给出预期的乘法结果 这就是我到目前为止的想法: 理论上,这应该是DX:AX中的无符号32位结果 当我在程序中使用此代码时,32位结果的低16位(或者换句话说,AX部分)是正确的,并且显示得很好。32位结果(DX部分)的高16位不正确

为了理解使用x86汇编语言的好处,我尝试编写一个16x16位乘法例程作为练习,它接受两个无符号的16位值,并使用移位和*addin*g将它们相乘,最后的32位结果存储在DX:AX

运行代码没有问题(换句话说,它编译得很好,并与我的链接程序一起运行),但是代码没有给出预期的乘法结果

这就是我到目前为止的想法:


理论上,这应该是DX:AX中的无符号32位结果

当我在程序中使用此代码时,32位结果的低16位(或者换句话说,AX部分)是正确的,并且显示得很好。32位结果(DX部分)的高16位不正确

有人能帮我找出我做错了什么吗?


提前感谢

似乎您需要在添加bx、bx之后将被乘数的一部分移到另一个寄存器中。这是因为每次移动bx而不移动进位时,顶部的位都会被截断。因此,您的原始代码只存储从bx到ax的进位之和,而不是乘法解的上半部分,在dx中

请在标签AddToResult后尝试此操作:

@AddToResult:
    add   bx,bx     ; add instead of shift?
    adc   di,di     ; shift part of multiplicand.
    or    cx,cx     ; fast zero check
    jnz   @lp

我还为被乘数的上16位选择了di,因为它已经被用于将进位添加到解决方案中。

我怀疑这是否真的比简单的
mov ax,cx快;mul bx
。或者你是想把这当作一个练习吗?@PMF主要是一个了解如何做的练习,尽管看到比使用mul指令更快的东西会很有趣(因为显然它是8086上仅次于div的最慢指令)。是的,在我20年前读的第一本asm书中,他们编写了一个计算器程序,但由于那时mul和div的速度确实非常慢,所以他们像这里一样使用位移位。但如果今天的微码体系结构仍然如此,我会非常惊讶。我试图手工找出我的代码出了什么问题,在看到你的建议和答案后,我意识到这正是我最初发布的代码中缺少的东西。你认为有没有更有效的方法用更少的指令来实现这一点?我想你可以在检查bx和cx是否都为0的循环之前删除代码。您的结果仍然是0,并且乘以0的特殊性不足以产生特殊情况。