《深入理解计算机系统》(原书第三版)家庭作业第三章(3.59)解答

**3.59 下面代码计算两个64位有符号值x和y的128位乘积,并将结果存储在内存中;

typedef __int128 int128_t;

void store_prod(int128_t *dest, int64_t x, int64_t y {
	*dest = x *(int128_t)y;

}


解析:

y in %rdx ,  x in %rsi
 汇编代码:
  store_prod:
    movq      %rdx, %rax               (y-->%rax)(设为b0)
    cqto                               (将%rax符号拓展位八字,拓展的y的高位数据保存在%rdx里,此值为y的高位:b1)
    movq      %rsi, %rcx               (x-->%rcx )(设为a0)
    sarq      $63,  %rcx               (拓展x的符号位为64位,并保存到%rcx,此值为x的高位:a1)
    imulq     %rax, %rcx               (k1 = b0*a1)
    imulq     %rsi, %rdx               (k2 = a0*b1)
    addq      %rdx, %rcx               (k1+k2)
    mulq      %rsi                     (128位无符号全乘法,计算 %rsi  * %rax  ,结果的高64位存储在:%rdx,低64位存储在:%rax)
    addq      %rcx, %rdx               (k1+k2+%rdx)  
    movq      %rax, (%rdi)             (存储最终的低64位结果到内存)   
    movq      %rdx, 8(%rdi)            (存储最终的高64位结果到内存)   
    ret




其实思路就在题目给的提示里面:
设:W=2^64
     a=(a1W +a0)          ##a1为a的高64位,a0为低64位
     b=(b1W +b0)          ##b1为b的高64位,b0为低64位

所以 a*b =(a1W +a0)*(b1W +b0)
              =(W * Wa1b1)+(Wa1b0)+(Wb1a0)+(a0b0)        # #因为第一项((W * W a1 b1) 已经超过128位,所以舍去)
              

所以最后得到a*b的结果是 :
          a*b=W (a1b0+b1a0)+(a0b0)

将结果结合上面的汇编注释就能解题了。

你可能感兴趣的:(作业)