Should I use "mul" or "imul" when multiplying a signed number to an unsigned number?

Viewed 7485

I have found out that both mul and imul can be used to multiply a signed number to an unsigned number.

For example:

global _start

section .data
    byteVariable DB -5

section .text
_start:

mov al, 2
imul BYTE [byteVariable]

You can replace imul with mul, and the result would still be the same (-10).

Are mul and imul exactly the same when multiplying a signed number to an unsigned number, or is there a difference between them?

3 Answers

x86 does have an instruction that multiplies signed bytes by unsigned bytes: SSSE3 pmaddubsw.

You can think of it as sign-extending one operand to 16 bits, zero-extending the other to 16 bits, then doing an NxN -> N-bit multiply. (For each SIMD element).

It also horizontally adds pairs of word products from adjacent bytes, but if you unpack the inputs with zeros (punpcklbw or pmovzxbw) then you can get each product separately.

Of course if you have SSE4.1 then you could just pmovsxbw one input and pmovzxbw the other input to feed a regular 16-bit pmullw, if you don't want pairs added.


But if you just want one scalar result, movsx / movzx to feed a regular non-widening imul reg, reg is your best bet.

As Harold points out, mul r/m and imul r/m widening multiplies treat both their inputs the same way so neither can work (unless the signed input is known to be non-negative, or the unsigned input is known to not have its high bit set, so you can treat them both the same after all.)

mul and imul also set FLAGS differently: CF=OF= whether or not the full result fits in the low half. (i.e. the full result is the zero-extension or sign-extension of the low half). For imul reg,r/m or imul reg, r/m, imm, the "low half" is the destination reg; the high half isn't written anywhere.

Another behavior of flags. For MUL: OF=CF=1 when carry bit changes upper half; For IMUL: OF=CF=1 when carry bit changes sign bit in low part (or just sign bit in result for 2 or 3 operands form)

Related