-2

I have this code:

mov rax, 0x93f3ffc2fbc7a1ce
mov rbx, 0x5862d8a05a385cbe
imul eax, ebx

How does imul work for 64-bit assembly? Will the overflow aex be written in the first 32 bits of rax?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Anka_Shch
  • 1
  • 1
  • 1
  • It works the same way as in 32 bit mode. – fuz Jan 08 '20 at 19:42
  • Possible duplicate of [Why do x86-64 instructions on 32-bit registers zero the upper part of the full 64-bit register?](//stackoverflow.com/q/11177137) or [x86\_64 registers rax/eax/ax/al overwriting full register contents](//stackoverflow.com/q/25455447), although I'm not sure what you mean by "overflow", or which direction you're counting bits from. Normally the "first" bits of a register are the low bits; we number them from 0 (lsb) to 63 (msb). PowerPC numbers from the top but x86 doesn't. – Peter Cordes Jan 08 '20 at 20:12

1 Answers1

2

Your code assembles to

0:  48 b8 ce a1 c7 fb c2    movabs rax,0x93f3ffc2fbc7a1ce
7:  ff f3 93
a:  48 bb be 5c 38 5a a0    movabs rbx,0x5862d8a05a385cbe
11: d8 62 58
14: 0f af c3                imul   eax,ebx

which uses the opcode 0F AF for imul. This instruction has 32-bit operand size so it only read EAX and EBX, and only writes EAX. This implicitly zero-extends into RAX, zeroing the upper 32 bits.

Unlike the 1-operand form of imul, the high-half of the 32x32 => 64-bit full multiply isn't written to EDX (or anywhere else like the high half of RAX); it's simply discarded or for efficiency not even calculated at all. See the documentation; 2-operand imul reg, r/m32 is just like add reg, r/m32 or or reg, r/m32 - it doesn't do any special weird stuff.

Using mov rax, imm64 before this 32-bit multiply is completely pointless, mov eax,0xfbc7a1ce would give exactly identical results. (The imul doesn't destroy RBX, so the upper 32 bits of the value you put into RBX is still there if you want to read it later. It has no effect on the imul instruction, though.)

Even better, imul eax, ebx, 0xfbc7a1ce could have avoided a mov.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Mark Snyder
  • 1,635
  • 3
  • 12
  • Writing a 32-bit register (EAX) *always* zero-extends into the full 64-bit register. [Why do x86-64 instructions on 32-bit registers zero the upper part of the full 64-bit register?](//stackoverflow.com/q/11177137). But yes, `mov r64,imm64` to feed a 32-bit operand-size imul is totally pointless. The multiply result isn't truncated, it was always a 32-bit multiply in the first place, only reading 32-bit inputs. (Or did you mean the 32x32 => 64-bit multiply coming out of the HW multiplier execution unit is truncated to 32-bit since this is the 2-operand form, not `imul ebx`? That's true) – Peter Cordes Jan 08 '20 at 20:08
  • @PeterCordes I meant the latter. I forgot about the zero-extension: thanks for the correction. – Mark Snyder Jan 08 '20 at 20:40
  • 1
    I fixed your answer for you. Don't leave wrong info in your answer, just fix it to what it should have said in the first place. – Peter Cordes Jan 08 '20 at 21:02