【问题标题】:Multiplying 64-bit number by a 32-bit number in 8086 asm在 8086 asm 中将 64 位数字乘以 32 位数字
【发布时间】:2019-08-24 10:12:04
【问题描述】:

即使启动问题的解决方案,我也遇到了问题。我尝试过考虑乘法是重复加法算法,但无论我考虑什么算法,我似乎都专注于一个问题——8086 中的最大寄存器大小是 16 位。

data segment
num1 dw 0102h,0304h,0506h,0708h
num2 dw 0102h,0304h
res dw ?,?,?,?,?,?
data ends

code segment
assume CS:CODE, DS:DATA
start:
mov ax,DATA
mov DS,ax

.............填写代码............

此时我被卡住了。即使是轻微的代码提示或算法也将不胜感激。

【问题讨论】:

  • 将你的数字分成 16 位块,使用你的 cpu 的 16x16=>32 乘法并酌情累积部分结果。请记住,您可以使用移位轻松乘以 2 的幂,或者在这种情况下简单地索引您的单词。
  • @Jester 我几乎是汇编编程的初学者,但会进一步探索它。如果你能用更简单的语言向我解释你的答案,可能还有一些代码片段,我将非常感激。
  • (a*2^48+b*2^32+c*2^16+d) * (e*2^16+f)。所有字母都是 16 位数字。执行乘法并将结果分组。
  • @Jester 很抱歉再次给您带来困扰,但我仍然不知道如何在代码中实现乘法
  • @JackMorton - 虽然最大寄存器大小为 16 位,但乘法指令在 dx:ax 中产生 32 位乘积。扩展精度乘法的基本算法类似于进行长手乘法。首先看看你是否能弄清楚如何将 32 位数乘以 16 位数,然后将 64 位数乘以 16 位数,然后将 64 位数乘以 32 位数。

标签: algorithm assembly x86-16 bigint extended-precision


【解决方案1】:

用 16 位 CPU 将 64 位数乘以 32 位数:

第 1 步:假设数字在“base 65536”中。例如,一个 64 位数字在十六进制中有 16 位数字(例如0x0123456789ABCDEF),在“base 65536”中将有 4 位数字(例如 {0123}{4567}{89AB}{CDEF});同样,32 位数字在“base 65536”中有 2 位数字。

第 2 步:要将一对数字相乘,请将第一个数字的每个数字与第二个数字的每个数字相乘,然后将其添加到结果中的正确位置。正确的位置取决于原始数字中每个数字的位置。例如(以十进制表示)90 * 30 你会做“9 * 3 = 27”并将它放在“数百”的地方(例如2700),因为第一个数字的右边有一个数字加上另一个数字第二个数字的右边,这意味着它需要到结果右边有 2 个数字的地方。

例子:

    0x0123456789ABCDEF * 0x87654321
  = {0123}{4567}{89AB}{CDEF} * {8765}{4321}

                      {0123}{4567}{89AB}{CDEF}
    *                             {8765}{4321}
    ------------------------------------------
    =                             {3600}{18CF}  (from 4321 * CDEF)
    +                       {6CEA}{484B}{0000}  (from 8765 * CDEF)
    +                       {2419}{800B}{0000}  (from 4321 * 89AB)
    +                 {48CF}{7D77}{0000}{0000}  (from 8765 * 89AB)
    +                 {1232}{E747}{0000}{0000}  (from 4321 * 4567)
    +           {24B4}{B2A3}{0000}{0000}{0000}  (from 8765 * 4567)
    +           {004C}{4E83}{0000}{0000}{0000}  (from 4321 * 0123)
    +     {0099}{E7CF}{0000}{0000}{0000}{0000}  (from 8765 * 0123)
    ------------------------------------------
    =     {009A}{0CD0}{5C28}{F5C1}{FE56}{18CF}
    ------------------------------------------
    = 0x009A0CD05C28F5C1FE5618CF

注意8086有“16位乘以16位=32位结果”指令(MUL);并且可以通过使用一条 ADD 指令,然后使用您需要的任意多条 ADC 指令,一次完成 16 位加法。

还请注意,您可以通过合并来避免一些添加。例如:

                      {0123}{4567}{89AB}{CDEF}
    *                             {8765}{4321}
    ------------------------------------------
    =                             {3600}{18CF}  (from 4321 * CDEF)
    +                       {6CEA}{484B}{0000}  (from 8765 * CDEF)
    +                       {2419}{800B}{0000}  (from 4321 * 89AB)
    +                 {48CF}{7D77}{0000}{0000}  (from 8765 * 89AB)
    +                 {1232}{E747}{0000}{0000}  (from 4321 * 4567)
    +           {24B4}{B2A3}{0000}{0000}{0000}  (from 8765 * 4567)
    +           {004C}{4E83}{0000}{0000}{0000}  (from 4321 * 0123)
    +     {0099}{E7CF}{0000}{0000}{0000}{0000}  (from 8765 * 0123)
    ------------------------------------------
    =                             {3600}{18CF}  (from 4321 * CDEF)
    +                 {48CF}{7D77}{0000}{0000}  (from 8765 * 89AB)
    +     {0099}{E7CF}{0000}{0000}{0000}{0000}  (from 8765 * 0123)
    +                       {6CEA}{484B}{0000}  (from 8765 * CDEF)
    +           {24B4}{B2A3}{0000}{0000}{0000}  (from 8765 * 4567)
    +                       {2419}{800B}{0000}  (from 4321 * 89AB)
    +           {004C}{4E83}{0000}{0000}{0000}  (from 4321 * 0123)
    +                 {1232}{E747}{0000}{0000}  (from 4321 * 4567)
    ------------------------------------------
    =     {0099}{E7CF}{48CF}{7D77}{3600}{18CF}  (THESE WERE MERGED WITHOUT ADDITION)
    +           {24B4}{B2A3}{6CEA}{484B}{0000}  (THESE WERE MERGED WITHOUT ADDITION)
    +           {004C}{4E83}{2419}{800B}{0000}  (THESE WERE MERGED WITHOUT ADDITION)
    +                 {1232}{E747}{0000}{0000}  (from 4321 * 4567)
    ------------------------------------------
    =     {009A}{0CD0}{5C28}{F5C1}{FE56}{18CF}
    ------------------------------------------
    = 0x009A0CD05C28F5C1FE5618CF

当然,因为对 ("base 65536") 数字进行乘法的顺序并不重要;您可以按最佳合并顺序进行所有乘法运算。

对于最终代码(有合并);你最终会得到 8 个 MUL 指令、3 个 ADD 指令和大约 7 个 ADC 指令。我懒得写代码了。 ;)

【讨论】:

猜你喜欢
  • 2012-11-07
  • 1970-01-01
  • 2014-09-11
  • 1970-01-01
  • 1970-01-01
  • 2016-09-14
  • 2014-01-09
  • 2012-07-26
  • 1970-01-01
相关资源
最近更新 更多