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
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."
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.
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.