【问题标题】:8086 Assembly: Multiply two 16 bit numbers to yield a 32 bit result without using the mul instruction8086 汇编:将两个 16 位数字相乘以产生 32 位结果,而无需使用 mul 指令
【发布时间】:2013-11-02 21:24:00
【问题描述】:

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

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

这是我目前想出的:


理论上这应该给我 DX:AX 中的无符号 32 位结果。

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

谁能帮我弄清楚我做错了什么?

提前致谢

【问题讨论】:

  • 我怀疑这真的比简单的mov ax, cx; mul bx 快。或者你是在尝试这个作为练习吗?
  • @PMF 主要是一个了解如何完成的练习,尽管看到比使用 mul 指令更快的东西会非常有趣(因为它显然仅次于 div 作为最慢的指令在 8086 上)。
  • 是的,大约 20 年前,在我阅读的第一本 asm 书中,他们编写了一个计算器程序,但因为那时 mul 和 div 确实非常慢,所以他们像您在这里一样使用按位移位。但如果今天的微码架构仍然如此,我真的会感到惊讶。

标签: assembly masm x86-16


【解决方案1】:

似乎您需要将部分被乘数移到add 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,因为它已经被用于将进位添加到解决方案中。

【讨论】:

  • 我试图手动找出我的代码出了什么问题,在看到您的建议和回答后,我意识到这正是我最初发布的代码中所缺少的。你认为有没有更有效的方法来用更少的指令来做到这一点?
  • 我猜你可以在检查 bx 和 cx 是否都为 0 的循环之前删除代码。你的结果仍然是 0,并且乘以 0 并不足以产生特殊情况。
猜你喜欢
  • 2016-01-24
  • 2015-10-11
  • 1970-01-01
  • 2012-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-13
相关资源
最近更新 更多