Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

imul vs mul

716 views
Skip to first unread message

io_x

unread,
Nov 6, 2009, 12:21:17 PM11/6/09
to

if sizeof(edi*69609)<=32bits
there is some difference in the result from
"mov eax, 69609
mul edi"
and this
"imul eax, edi, 69609"
i think not.

and if sizeof(edi*69609)>32bits
then eax will be different? (the only eax)
thank you
Buon Giorno


BGB / cr88192

unread,
Nov 6, 2009, 6:01:11 PM11/6/09
to

"io_x" <a...@b.c.invalid> wrote in message
news:4af4595b$0$1102$4faf...@reader3.news.tin.it...

AFAICT, the only real difference between them is how CF and OF are set
following the multiply, where each sets the flags depending on different
criteria.

EAX and EDX (or RAX and RDX), are the same in both cases.


>


Rod Pemberton

unread,
Nov 6, 2009, 6:40:47 PM11/6/09
to
"io_x" <a...@b.c.invalid> wrote in message
news:4af4595b$0$1102$4faf...@reader3.news.tin.it...
>
> if sizeof(edi*69609)<=32bits
> there is some difference in the result from
> "mov eax, 69609
> mul edi"

edx:eax = edi * eax
edx:eax = edi * 69609

> and this
> "imul eax, edi, 69609"

eax = edi * 69609

> i think not.

They are not the same. But, eax might be identical.

The first stores unsigned mulitply of 64-bit result into edx:eax pair. The
second stores a signed mulitply 64-bit result truncated to 32-bits in eax.

Also, from the documents, it seems "mul" only does unsigned. "imul" does
the same as "mul" for one-operand forms. For two and three operand forms,
it seems "imul" can do both signed and unsigned correctly since on the low
order result (lower 32-bits of 64-bits) is stored, i.e., the signage is
lost.

> and if sizeof(edi*69609)>32bits
> then eax will be different? (the only eax)

I think eax should be the same according to what I read. edx and the
unsaved upper 32-bits of the other form should be different.

BUT, you shouldn't take my word for it. I've almost never used these
instructions. I've only read the manual...

So, code a loop. Multiply values for both. Compare the values. Are they
the same? Rewrite the loop to use constant 000FF000h instead of 10FE9
(69609). Are they still the same? 0FFFFFFFh? FFFFFFFFh? FA23A5A5h?
0000D912h?


+++++++
This is different also:

"imul edi, 69609"

edi = edi * 69609

This is the same as the original "mul" but with "imul", according to the
doc's:

"mov eax, 69609
imul edi"

edx:eax = edi * eax
edx:eax = edi * 69609


Rod Pemberton


Rod Pemberton

unread,
Nov 6, 2009, 6:56:59 PM11/6/09
to
"BGB / cr88192" <cr8...@hotmail.com> wrote in message
news:hd29rm$gvc$1...@news.albasani.net...

?

Only the one-operand form of "imul" sets a register pair such as EDX:EAX.
The two- and three-operand forms, just sets the chosen destination register,
at least according to the doc's I've got. The OP used the three-operand
form of "imul" in the second example above. I.e., EAX and EDX from the
first example can't be the same as in the second example.


RP


BGB / cr88192

unread,
Nov 6, 2009, 7:12:25 PM11/6/09
to

"Rod Pemberton" <do_no...@nohavenot.cmm> wrote in message
news:hd2c9j$2ki$1...@aioe.org...

> "io_x" <a...@b.c.invalid> wrote in message
> news:4af4595b$0$1102$4faf...@reader3.news.tin.it...
>>
>> if sizeof(edi*69609)<=32bits
>> there is some difference in the result from
>> "mov eax, 69609
>> mul edi"
>
> edx:eax = edi * eax
> edx:eax = edi * 69609
>
>> and this
>> "imul eax, edi, 69609"
>
> eax = edi * 69609
>
>> i think not.
>
> They are not the same. But, eax might be identical.
>
> The first stores unsigned mulitply of 64-bit result into edx:eax pair.
> The
> second stores a signed mulitply 64-bit result truncated to 32-bits in eax.
>
> Also, from the documents, it seems "mul" only does unsigned. "imul" does
> the same as "mul" for one-operand forms. For two and three operand forms,
> it seems "imul" can do both signed and unsigned correctly since on the low
> order result (lower 32-bits of 64-bits) is stored, i.e., the signage is
> lost.
>

for the one operand forms, they are almost the same, but differ in terms of
CF and OF (typically, we don't care about them in this case anyways).

EDX/RDX should not differ, since the general operation is the same either
way (multiplication is equivalent for signed and unsigned integers).

(note that this does not hold for div and idiv, since division is actually
different between the signed and unsigned cases).


for the 2/3 operand forms, they differ, in that only imul has 2 and 3
operand forms...

>> and if sizeof(edi*69609)>32bits
>> then eax will be different? (the only eax)
>
> I think eax should be the same according to what I read. edx and the
> unsaved upper 32-bits of the other form should be different.
>

I don't think they will be different, but experiment tells all...

BGB / cr88192

unread,
Nov 6, 2009, 8:26:12 PM11/6/09
to

"Rod Pemberton" <do_no...@nohavenot.cmm> wrote in message
news:hd2d7u$3kj$1...@aioe.org...

yeah, I had missed this, and had been thinking of the single-operand form...


>
> RP
>
>


io_x

unread,
Nov 8, 2009, 2:00:02 PM11/8/09
to
"BGB / cr88192" <cr881..@hotmail.com> ha scritto nel messaggio
news:hd2e19$mq2$1...@news.albasani.net...

>>> and if sizeof(edi*69609)>32bits
>>> then eax will be different? (the only eax)
>>
>> I think eax should be the same according to what I read. edx and the
>> unsaved upper 32-bits of the other form should be different.
>>
>
> I don't think they will be different, but experiment tells all...

Thank you

H. Peter Anvin

unread,
Nov 9, 2009, 1:27:28 AM11/9/09
to BGB / cr88192
On 11/06/2009 04:12 PM, BGB / cr88192 wrote:
>
> EDX/RDX should not differ, since the general operation is the same either
> way (multiplication is equivalent for signed and unsigned integers).
>

No, they aren't. They are the same only for single-width output (as the
2- and 3-operand operations produce), but not for double-width output.

-hpa

BGB / cr88192

unread,
Nov 9, 2009, 9:23:09 AM11/9/09
to

"BGB / cr88192" <cr8...@hotmail.com> wrote in message
news:hd2e19$mq2$1...@news.albasani.net...
>
<snip>

>
> for the one operand forms, they are almost the same, but differ in terms
> of CF and OF (typically, we don't care about them in this case anyways).
>
> EDX/RDX should not differ, since the general operation is the same either
> way (multiplication is equivalent for signed and unsigned integers).
>
> (note that this does not hold for div and idiv, since division is actually
> different between the signed and unsigned cases).
>
<snip>

>
> I don't think they will be different, but experiment tells all...
>

I went and tested, and it seems I was incorrect:
the high order bits do seem to differ...

however, I am at a lost as to the reason (ie: what exactly is going on with
the bits as to cause this effect...).

seems if I convert both to 64 bits first (and do a 64 bit multiply), the
result is the same in both cases.

if I manually sign or zero extend them (my guess as to what was going on),
the results differ, but not in the same way as my prior test (manual
sign/zero extension yeilds a 25% match rate, however my initial tests showed
a 50% match rate).


grr...


Phil Carmody

unread,
Nov 9, 2009, 3:03:04 PM11/9/09
to
"BGB / cr88192" <cr8...@hotmail.com> writes:
> "BGB / cr88192" <cr8...@hotmail.com> wrote in message
> news:hd2e19$mq2$1...@news.albasani.net...
>>
> <snip>
>>
>> for the one operand forms, they are almost the same, but differ in terms
>> of CF and OF (typically, we don't care about them in this case anyways).
>>
>> EDX/RDX should not differ, since the general operation is the same either
>> way (multiplication is equivalent for signed and unsigned integers).
>>
>> (note that this does not hold for div and idiv, since division is actually
>> different between the signed and unsigned cases).
>>
> <snip>
>>
>> I don't think they will be different, but experiment tells all...
>>
>
> I went and tested, and it seems I was incorrect:
> the high order bits do seem to differ...

It's an artifact of 2's-complement representation.

Let the limb base be H, so 32x32->64 mults would have H=2^32.

Consider the 'pure' base case multiplication to be the unsigned one:
A * B -> C*H+D

Now consider what happens if A is a bit-pattern that would be
considered -ve were registers to have signs. So A really
represents A'=(A-H) numerically.

You want (A-H)*B = A*B - H*B
You have A*B = C*H + D from the base case multiplication above.
So A' * B = C*H + D - H*B = (C-B)*H + D

So there clearly is a difference in the top bits only.

This is why architectures (plural? I've only used 1) which support
multiplication but do not support double-width mutliplication only
offer one single-width muliplication operation. There isn't a 2nd
to offer. And all those that offer double-width offer it in two
flavours, signed and unsigned. (Sometimes this is via 3 opcodes -
one mullo, and two separate mulhis.)

Phil
--
Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1

BGB / cr88192

unread,
Nov 9, 2009, 3:37:19 PM11/9/09
to

"Phil Carmody" <thefatphi...@yahoo.co.uk> wrote in message
news:87zl6v7...@kilospaz.fatphil.org...

> "BGB / cr88192" <cr8...@hotmail.com> writes:
>> "BGB / cr88192" <cr8...@hotmail.com> wrote in message
>> news:hd2e19$mq2$1...@news.albasani.net...
>>>
>> <snip>
>>>
>>> for the one operand forms, they are almost the same, but differ in terms
>>> of CF and OF (typically, we don't care about them in this case anyways).
>>>
>>> EDX/RDX should not differ, since the general operation is the same
>>> either
>>> way (multiplication is equivalent for signed and unsigned integers).
>>>
>>> (note that this does not hold for div and idiv, since division is
>>> actually
>>> different between the signed and unsigned cases).
>>>
>> <snip>
>>>
>>> I don't think they will be different, but experiment tells all...
>>>
>>
>> I went and tested, and it seems I was incorrect:
>> the high order bits do seem to differ...
>
> It's an artifact of 2's-complement representation.
>
> Let the limb base be H, so 32x32->64 mults would have H=2^32.
>
> Consider the 'pure' base case multiplication to be the unsigned one:
> A * B -> C*H+D
>

or, another way to think about it:
AB
CD *
____
__BD
_AD_
_BC_
AC__

so, it is a sort of recursive pattern, starting with single bits and
allowing ever bigger multiplies to be constructed from smaller ones...

but, then they have to confuse me by adding sign extension into the mix...


> Now consider what happens if A is a bit-pattern that would be
> considered -ve were registers to have signs. So A really
> represents A'=(A-H) numerically.
>
> You want (A-H)*B = A*B - H*B
> You have A*B = C*H + D from the base case multiplication above.
> So A' * B = C*H + D - H*B = (C-B)*H + D
>
> So there clearly is a difference in the top bits only.
>
> This is why architectures (plural? I've only used 1) which support
> multiplication but do not support double-width mutliplication only
> offer one single-width muliplication operation. There isn't a 2nd
> to offer. And all those that offer double-width offer it in two
> flavours, signed and unsigned. (Sometimes this is via 3 opcodes -
> one mullo, and two separate mulhis.)
>

and somehow I had never really noticed or thought much about the
difference...

next thought:
why then do assemblers not support multi-argument 'mul' forms and simply
alias them to the imul encodings?...

my guess is that there is maybe no good reason to, it may further confuse
the mul/imul issue, or it would cause an issue WRT disassembly (which form
was intended?), ...

in my case, I just typed what the listings said, and noted it as an oddity
but didn't think too much more about it...

James Harris

unread,
Nov 9, 2009, 5:25:05 PM11/9/09
to
On 9 Nov, 20:03, Phil Carmody <thefatphil_demun...@yahoo.co.uk> wrote:

...

> > I went and tested, and it seems I was incorrect:
> > the high order bits do seem to differ...
>
> It's an artifact of 2's-complement representation.
>
> Let the limb base be H, so 32x32->64 mults would have H=2^32.
>
> Consider the 'pure' base case multiplication to be the unsigned one:
> A * B -> C*H+D
>
> Now consider what happens if A is a bit-pattern that would be
> considered -ve were registers to have signs. So A really
> represents A'=(A-H) numerically.
>
> You want (A-H)*B = A*B - H*B
> You have A*B = C*H + D from the base case multiplication above.
> So A' * B = C*H + D - H*B = (C-B)*H + D
>
> So there clearly is a difference in the top bits only.

Thanks for explaining this. Does this mean that

imul ebx

and

mul ebx
sub edx, ebx

have the same effect on the bits in edx and eax? It doesn't seem
intuitive.

James

Alexei A. Frounze

unread,
Nov 9, 2009, 5:58:35 PM11/9/09
to

IFF eax was < 0 before mul, then you'd need to subtract ebx from edx.
Likewise, to make a full correct signed multiplier out of the unsigned
one, after that you'd need to do the same in the other direction:
IFF ebx was < 0 before mul, subtract old eax from edx after mul.

Yes, it doesn't seem very intuitive, but that's how it works. Write a
simple test and compare signed multiplication out of the box with thus
constructed.

Alex

0 new messages