我想将两个64位无符号数相乘,并将结果存储在一个128位变量中。我是按照链接www.example.com中给出的方式做的https://www.plantation-productions.com/Webster/www.artofasm.com/Windows/HTML/AdvancedArithmetica2.html#1007619,迈克尔·伯尔在回答川原的问题(How can I multiply two 64-bit numbers using x86 assembly language?)时提到了这一点。下面是我的代码:
program exercise;
static
qw1:qword:= 956_3547_6850_2300_5452;//$84B8_8BF3_1E4E_3B0C
qw2:qword:= 956_3547_6850_2300_5452;//$84B8_8BF3_1E4E_3B0C
//qw1:qword:= 18_446_744_073_709_551_615;//$FFFF_FFFF_FFFF_FFFF
//qw2:qword:= 18_446_744_073_709_551_615;//$FFFF_FFFF_FFFF_FFFF
prd:lword :=0;
#include("Stdlib.hhf");
begin exercise;
mov((type dword qw1[0]),eax);
mul((type dword qw2[0]),eax);
mov(eax,(type dword prd[0]));
mov(edx,ecx);
mov((type dword qw1[4]),eax);
mul((type dword qw2[0]),eax);
add(ecx,eax);
mov(eax,ebx);
adc(0,edx);
mov(edx,ecx);
mov((type dword qw1[0]),eax);
mul((type dword qw2[4]),eax);
add(ebx,eax);
mov(eax,(type dword prd[4]));
adc(ecx,edx);
mov(edx,ecx);
mov((type dword qw1[4]),eax);
mul((type dword qw2[4]),eax);
add(ecx,eax);
mov(eax,(type dword prd[8]));
adc(0,edx);
mov(edx,(type dword prd[12]));
stdout.put(prd, " ",(type uns128 prd));
end exercise;
字符串
运行程序后,此代码准确地回答两个较小的上限数的乘积
(in在这种情况下,确切的答案是:44CED55C313E2724C1798E86D8EE8890)但对于下面两个较大的数字,答案与精确值相差甚远
(in在这种情况下,确切的答案是:FFFFFFFFFFFFFE000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
但是当我将最后一个adc(0,edx);
更改为adc(1,edx);
时,问题就解决了。
1.我的问题是,这个数字1是从哪里来的?
1.我错在哪里?
1.如何修改此程序?
这个问题对我来说是一个严峻的挑战,我很感谢我的朋友们在这件事上指导我。
2条答案
按热度按时间nkhmeac61#
您跳过了注解源代码。
第二个“中间子产品”的增加产生了一个你不考虑的进位。
通常,任一加法都可以生成进位:只是处理它们。
第二个“中间子积”的加法不会为两个更大的数字生成进位(Hashem alizadeh)
它应该:
FFFF FFFF×FFFF FFFF = FFFF FFFE 0000 0001
字符串
b0zn9rqh2#
@greybeard是对的,因为第二个叉积的加法产生了另一个进位。研究99 * 99相乘产生9801的类似(十进制)情况。
FFFF FFFF乘以FFFF本身得到FFFF FFFE 0000 0001(类似于9 * 9 = 81)。
然后,必要的添加产生:
字符串
您可以尝试下一个解决方案:
型