8086 asm 中 64 位数字乘以 32 位数字

0 algorithm assembly bigint extended-precision x86-16

我什至在启动问题的解决方案时遇到问题。我曾尝试考虑乘法是重复加法算法,但无论我考虑什么算法,我似乎都专注于一个问题——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
Run Code Online (Sandbox Code Playgroud)

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

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

Bre*_*dan 5

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

第 1 步:假设数字在“基数 65536”中。例如,一个 64 位数字在十六进制中有 16 位数字(例如0x0123456789ABCDEF),而在“base 65536”中有 4 位数字(例如 {0123}{4567}{89AB}{CDEF});以同样的方式,一个 32 位的数字在“基数 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
Run Code Online (Sandbox Code Playgroud)

注意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
Run Code Online (Sandbox Code Playgroud)

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

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