2015-10-05 152 views
-2

以下代碼計算x和y的乘積並將結果存儲在內存中。數據類型ll_t被定義爲 等於long long。在32位機器上實現64位算術 - 彙編代碼

GCC產生執行計算以下組件的代碼:

typedef long long ll_t; 

void store_prod(ll_t *dest, int x, ll_t y) 
{ 
*dest = x*y; 
} 

DEST在的%ebp + 8,X在的%ebp + 12,Y在的%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) 

此代碼使用三次乘法來實現在32位機器上實現64位算術運算所需的多精度算法 。描述用於計算產品的算法,並註釋彙編代碼以顯示其如何實現您的算法。

問題:第5行是做什麼的?它註冊ecx有什麼價值? 第11行也做了什麼?

+0

如果您的偏移量爲8,12,16和20,那麼它們都是32位。 64位操作數會有8個字節的偏移量。 – stark

+0

@stark錯誤。 'dest'是一個指針,所以4個字節。 'x'確實是32位。 'y'是64位,從+16開始,低dword,+ 20高dword。 – Jester

+0

[LEA指令的目的是什麼?](http://stackoverflow.com/q/1658294/995714),[MOV和LEA有什麼區別](http://stackoverflow.com/q/1699748/ 995714) –

回答

2

第5行:它將一些局部變量的值複製到ECX。由於我們缺少原始功能代碼的一部分,因此此列表中的值未知。

第11行:它相當於:EDX = EDX + ECX。 LEA指令用於計算內存值的EA並將該EA存儲到目標寄存器,因此可用於快速執行加法和常數乘法。

+1

第5行復制'y'操作數的高位字。 – Jester

+0

所以添加了這個功能。但即時通訊仍然不確定eax(x)在下一行(第6行)中的乘數。 – user2800591

+2

這是一個愚蠢的方式做一個32 * 64乘以64位擴展到64位和64 * 64。 – Jester