我甚至在开始解决问题时都遇到了问题。我已经尝试过考虑乘法是重复加法算法,但是无论我考虑哪种算法,我似乎都固定在一个问题上— 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
..........填写代码.........
这时我被困住了。即使是一小段代码提示或仅算法,也将不胜感激。
答案 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
指令。我懒得写代码。 ;)