Why can't we do arithmetic on an operand in x86 asm?

107 Views Asked by At

mov rax,r9+rcx*2

Why is this invalid syntax? Doesn't this count as "mov r64,r/m64" ? I'm a beginner so I'm sorry for my ignorance.

It becomes valid when the expression is enclosed in square brackets mov rax,[r9+rcx*2]. Why is that?

3

There are 3 best solutions below

0
Sep Roland On BEST ANSWER
mov rax,r9+rcx*2

This is an invalid syntax because the source operand (rightmost operand) contains registers and operations that the assembler can't perform at compile-time simply because the assembler does not know what values these registers contain. Only at runtime are these values revealed.

Using the square brackets, [r9 + rcx * 2] becomes a valid addressing mode that uses a base register (R9) and an index register (RCX) that gets scaled by a factor (2).

mov rax, [r9 + rcx * 2]

When combined with the mov instruction, the memory contents at the calculated address will be returned in the indicated register (RAX).

lea rax, [r9 + rcx * 2]

When combined with the lea instruction, the calculated address itself will be returned in the indicated register (RAX).

In both cases, the address calculation happens at runtime.

0
Erik Eidt On

The hardware machine code is very specific in what it allows and doesn't allow by way of encoding.

There is no general purpose expression capability in the machine code by way of a single, maybe larger instruction, but certain very limited computations are allowed, for one, by addressing modes.

Many assemblers will allow computation expressions if all the operands are constant and it can figure it out during program construction.

For general purpose expressions we need to use a high level language — which will translate into machine code using one or more instructions as needed.

And for assembly programmers, multiple instructions for small computations is normal.

3
Atakan Arslan On

In order to perform mathematical operations, relevant commands in assembly language must be used. You cannot perform arithmetic operations directly with registers in assembly language. You cannot do like these: rcx * 2 or r9 + 5. If you want to do "mov rax, r9 + rcx * 2" operation legally, you can do it with the help of the following commands:

  1. imul rcx, 2 ---> rcx = rcx * 2
  2. add r9, rcx ---> r9 = r9 + rcx --> now r9 is equal to r9 + rcx * 2
  3. mov rax, r9 ---> we performed mov rax, r9 + rcx * 2 operation legally and indirectly.