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)
.....填写代码.......
在这一点上,我被卡住了。即使是轻微的代码提示或算法也将不胜感激。
使用 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条指令。懒得写代码了。;)