mul and memory allocation in registers edx::eax wi

2020-04-20 06:53发布

问题:

I am trying to understand the logic of using the "mul" operand in the assembler(i am using Visual Studio Community and MASM). Why, after "mul ebx" the result is changing also edx, and not only the eax? "The result(of MUL) is stored in register AX, register pair DX:AX, or register pair EDX:EAX (depending on the operand size), with the high-order bits of the product contained in register AH, DX, or EDX". So is the location depending on the size of the operand?In which case?

.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 

回答1:

Yes, as you said it depends on operand size which is not the actual value of the operand. You always get double size output, overflow or not. mul ebx is 32 bit, hence you get 64 bit output in edx:eax where edx may be zero.

As Peter Cordes pointed out, if you know you won't need the top half of the result, "you can and should use the 2-operand or 3-operand immediate form of IMUL". Don't be fooled by the signedness, to quote the instruction set reference: "The two- and three-operand forms may also be used with unsigned operands because the lower half of the product is the same regardless if the operands are signed or unsigned."



回答2:

The MUL and IMUL instructions always generate output that is twice the width of the inputs. So:

  • 8 bit inputs (one in AL) give a 16 bit output (in AX)
  • 16 bit inputs (one in AX) give a 32 bit output (in DX:AX)
  • 32 bit inputs (one in EAX) give a 64 bit output (in EDX:EAX)

Note that the relevant width is always the width of the argument (and the implicit A register), not the minimum width to hold either of the values. A 32-bit multiply by zero will (slowly) set EDX:EAX to all zeros.



回答3:

The unsigned multiply (MUL instruction) will always sign-extend (well, zero-extend, since it's unsigned) into EDX when it is passed an r/m32-sized operand, regardless of whether or not EDX would contain anything but zeroes.

This applies to the signed variant, IMUL, as well, though in that case EDX might contain nothing but FF bytes if the result was negative.