深入理解计算机系统(英文版 第二版)中的第三章家庭作业3.55想了一个晚上也没有想出来到底是怎么回事。百度也没有百度出结果,而用google搜索相关内容,终于找到了其中的“猫腻”。
如果想要直接看,则点击下面链接。
http://stackoverflow.com/questions/11680720/implement-64-bit-arithmetic-on-a-32-bit-machine
书中,3.55题在P329页,题目略有不同,但原理一致。
The following code computes the product of x and y and stores the result in memory. Data type ll_t is defined to be equivalent to long long.
1 typedef long long ll_t; 2 void store_prod(ll_t *dest, int x, ll_t y) { 3 *dest = x*y; 4 }
gcc generates the following assembly code implementing the computation:
dest at %ebp+8, x at %ebp+12, y at %ebp+16
1 movl 16(%ebp), %esi 2 movl 12(%ebp), %eax 3 movl %eax, %edx 4 sarl $31, %edx 5 movl 20(%ebp), %ecx 6 imull %eax, %ecx 7 movl %edx, %ebx 8 imull %esi, %ebx 9 addl %ebx, %ecx 10 mull %esi 11 leal (%ecx,%edx), %edx 12 movl 8(%ebp), %ecx 13 movl %eax, (%ecx) 14 movl %edx, 4(%ecx)
This code uses three multiplications to implement the multiprecision arithmetic required to implement 64-bit arithmetic on a 32-bit machine. Describe the algorithm used to compute the product, and annotate the assembly code to show how it realizes your algorithm.
简要地分析一下上述代码的原理。我们知道x是32位,而y是64位,我们将x按符号扩展为64位,这一步即为汇编中3、4行的作用。实际上,x在符号扩展前后,与y相乘的64位结果是一样的。
x=xhigh*232+xlow
y=yhigh*232+ylow
x*y=(xhigh*yhigh)*264 (1)
+(xlow*yhigh+xhigh*ylow)*232 (2)
+xlow*ylow (3)
我们要取它的低64位结果,故(1)直接省略;
64位结果中,低32位的结果可以直接使用(3)计算出来;
高32位结果由两部分构成:(2)的低32位结果+(3)的高32位结果;
要得到(3)的高32位结果,我们需要使用mul的单操作数形式,在edx中保存乘积的高32位。需要注意的是这里使用mul无符号乘法运算,是由于y是64位的,低32位可以看作无符号数,因此,如果使用imul,虽然低32位的结果是正确的,但是高32位结果却是错误的。
作者:Chenny Chen
出处:http://www.cnblogs.com/XjChenny/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。