深入理解计算机系统(英文版 第二版)中的第三章家庭作业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位结果却是错误的。

posted on 2013-04-06 10:13  Chenny Chen  阅读(1137)  评论(0编辑  收藏  举报