0

即使启动问题的解决方案,我也遇到了问题。我曾尝试考虑乘法是重复加法算法,但无论我考虑什么算法,我似乎都专注于一个问题——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

…………填写代码…………

在这一点上,我被困住了。即使是轻微的代码提示或算法也将不胜感激。

4

1 回答 1

5

使用 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”)数字进行乘法的顺序并不重要;您可以按最佳合并顺序进行所有乘法运算。

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

于 2019-04-03T04:05:01.930 回答