-1

I don't understand what this assembly code does.

imul   -0x8(%rsp, %rbx, 4), %eax
cmp    %eax, -0x4(%rsp, %rbx, 4)

I get what the instructions imul and cmp do, but I don't understand what -0x4(%rsp, %rbx, 4) and -0x8(%rsp, %rbx, 4) means. I can provide more context if needed, but what I really want is just a literal translation of these two lines. What is being stored on in %eax on the first line? The product of %rbx*4 and %rsp - 8?

  • 2
    `-0x8(%rsp, %rbx, 4)` is a memory operand. In AT&T syntax it is displacement(base, index, scale) where the computation is displacement+base+index*scale. Base and index have to be registers, scale is a value 1,2,4,8 and displacement can be up to a 32-bit signed value. – Michael Petch Oct 25 '18 at 20:29

1 Answers1

2

What is being stored in %eax is the product of -0x8(%rsp, %rbx, 4) and %eax.

And -0x8(%rsp, %rbx, 4) is the contents of memory location %rsp + 4*%rbx - 8.

TonyK
  • 16,761
  • 4
  • 37
  • 72
  • The code in the question looks like 64-bit code. But the operand size here is still 32-bits somehow (by default?). Does the memory location point to a 32-bits operand because %eax is specified instead of %rax? – E. van Putten Oct 25 '18 at 20:51
  • @E.vanPutten: I have no experience of writing 64-bit x86 assembly code. But I assume that the addresses are 64 bits, and the operands (in this instruction) are 32 bits. Just as you can perform 8- or 16-bit multiplications in 32-bit mode. – TonyK Oct 25 '18 at 20:53
  • Yes, it makes a lot sense that the memory addresses are 64-bits. Otherwise these displacement calculations could see wrap-arounds. I take it that the default operand size is 32-bit, and that things only get promoted if you mention a 64-bit register. – E. van Putten Oct 25 '18 at 21:01
  • @E.vanPutten: No, I think the default operand size is 64 bits. But here the use of `%eax` instead of `%rax` specifies a 32-bit arithmetic operation. (Address calculations are always 64-bit.) – TonyK Oct 25 '18 at 21:05
  • Section Operating Modes in https://en.wikipedia.org/wiki/X86-64 says it is 32-bit. Don't know why, maybe to make it easier to port legacy software. – E. van Putten Oct 25 '18 at 21:14
  • 1
    What a dreadful mess! – TonyK Oct 25 '18 at 21:34
  • 1
    `imul -0x8(%rsp, %rbx, 4), %eax` under the hood takes the 32-bit value at memory address `-0x8(%rsp, %rbx, 4` , multiplies that by _EAX_. The result internally is twice the width of the source operand. The lower 32-bits of the result will placed in _EAX_ (CF will be set accordingly) and the upper 32-bits of RAX will be overwritten with zeroes automatically (because the CPU in 64-bit mode zero extends any 32-bit destination register through the entire 64-bit register (RAX in this case) – Michael Petch Oct 25 '18 at 21:51
  • 2
    In 64-bit mode, the instruction’s default operation size is 32 bits. This can be overridden by a REX.W prefix – Michael Petch Oct 25 '18 at 21:54