2011-10-13 17 views
1

說我大會如何IMUL操作碼(只有一個OPRAND)轉換爲C代碼

EDX = 0xA28

EAX = 0x0A280105

我運行此ASM代碼

IMUL EDX

這據我瞭解,只使用EAX ..如果指定了一個oprand

所以在C代碼應該是這樣

EAX *= EDX;

是否正確?

看着調試器後,我發現EDX也被改變了。

0x0A280105 * 0xA28 = 0x67264A5AC8

調試器

EAX = 264A5AC8 EDX = 00000067

現在,如果你把答案 0x67264A5AC8和分裂第一六角對

0x67 264A5AC8 你可以清楚地看到,爲什麼EDXEAX現在的樣子他們是。

好吧,所以溢出發生..因爲它不能存儲這樣一個巨大的數字到32位。所以它開始在EDX中使用額外的8位

但我的問題是如何在C代碼中執行此操作以獲得相同的結果?

我猜它會像

EAX *= EDX; 
EDX = 0xFFFFFFFF - EAX; //blah not good with math manipulation like this. 
+1

本指令始終使用EDX存儲產品,無論產品的價值是否可以表示結果是否不丟失32位。 –

回答

1

的IMUL指令實際上產生的結果兩次操作數的大小(除非你使用的是可以指定目標的新版本之一)。所以:

imul 8bit -> result = ax, 16bits 
imul 16bit -> result = dx:ax, 32bits 
imul 32bit -> result = edx:eax, 64bits 

要做到這在C將取決於編譯器,但有些將工作這樣做:

long result = (long) eax * (long) edx; 
eax = result & 0xffffffff; 
edx = result >> 32; 

這是假定長爲64位。如果編譯器沒有64位數據類型,那麼計算結果變得更加困難,您需要進行長乘法。

您可以隨時聯繫imul指令。

+0

不能內聯imul指令,我想實際上將ASM模擬爲C代碼..所以寄存器然後會生成我..'CALL EAX's'這是我構建此工具以獲取所有運行時CALL的唯一原因而沒有真正運行程序 – SSpoke