寄存器中的mul和内存分配edx :: eax with masm

时间:2016-12-07 16:14:03

标签: visual-studio assembly x86 masm

我试图理解在汇编程序中使用“mul”操作数的逻辑(我使用的是Visual Studio Community和MASM)。 为什么,在“mul ebx”之后,结果也改变了edx,而不仅仅是eax? “结果(MUL)存储在寄存器AX,寄存器对DX:AX或寄存器对EDX:EAX(取决于操作数大小)中,产品的高位位包含在寄存器AH,DX或EDX”。 那么位置取决于操作数的大小?在哪种情况下?

.586
.model flat,c
.stack 100h
.data

.code

 doit proc

        ;EAX = 0062EEF0 EBX = 7EFDE000 ECX = 0029FD00 EDX = 00000000     
     mov eax,8;
        ;EAX = 00000008
     mov ebx,4
        ;EBX = 00000004 
     mov edx,23498
        ;EDX = 00005BCA 
     mul ebx
        ;EAX = 00000020 EDX = 00000000 ????  4*8 =20(hexa).So, there is no 
                                       ;overflow;why is edx changing too?


 doit endp

end 

3 个答案:

答案 0 :(得分:3)

是的,正如您所说,它取决于操作数大小,而不是操作数的实际值。你总是得到双倍大小的输出,溢出与否。 mul ebx为32位,因此edx:eaxedx的输出为64位,其中using System.Net; using System.Text.RegularExpressions; public string GetLabelValue(string url) { // download your web page content WebClient client = new WebClient(); string downloadString = client.DownloadString(url); // regular expression var pattern = @"<label.+id=""lblTest"".{0,}>(.+)</label>"; var match = Regex.Match(downloadString, pattern, RegexOptions.IgnoreCase); // getting the label value var labelValue = match.Groups[1].Value; return labelValue; } 可能为零。

正如Peter Cordes指出的那样,如果你知道你不需要结果的上半部分,“你可以而且应该使用IMUL的2操作数或3操作数直接形式”。不要被签名所迷惑,引用指令集引用:“两个和三个操作数形式也可以与无符号操作数一起使用,因为无论操作数是否为操作数,产品的下半部分都是相同的已签名或未签名。“

答案 1 :(得分:3)

MULIMUL指令始终生成两倍于输入宽度的输出。所以:

  • 8位输入(AL中的一个)给出16位输出(在AX中)
  • 16位输入(AX中的一个)给出32位输出(在DX:AX中)
  • 32位输入(EAX中的一个)给出64位输出(在EDX:EAX中)

请注意,相关宽度始终是参数(和隐式A寄存器)的宽度,而不是保存任一值的最小宽度。 32位乘零将(缓慢)将EDX:EAX设置为全零。

答案 2 :(得分:1)

无符号乘法(MUL指令)总是符号扩展(好,零扩展,因为它是无符号的)到EDX时它是r/m32传递EDX大小的操作数,无论EDX是否包含除零之外的任何内容。

这也适用于已签名的变体IMUL,但在这种情况下FF如果结果为负则可能只包含NaN个字节。