在8086 ASM中将64位数字乘以32位数字

时间:2019-04-03 01:23:24

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

我甚至在开始解决问题时都遇到了问题。我已经尝试过考虑乘法是重复加法算法,但是无论我考虑哪种算法,我似乎都固定在一个问题上— 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

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

这时我被困住了。即使是一小段代码提示或仅算法,也将不胜感激。

1 个答案:

答案 0 :(得分:4)

要使用16位CPU将64位数字乘以32位数字:

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

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

示例:

    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

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

对于最终代码(合并);您最终将获得8条MUL指令,3条ADD指令和大约7条ADC指令。我懒得写代码。 ;)