Why does my assembly use "+" and "*" signs instead of instructions for calculating addresses?

StackOverflow https://stackoverflow.com/questions/23659656

  •  22-07-2023
  •  | 
  •  

Вопрос

I have this assembly:

movzx eax, r8w
add r8d, 0x4
movzx edx, r8w
cmp edx, 0x1f4
movdqu xmm3, xmmword ptr [r9+rax*4+0xfb0]   ; Why "+" instead of ADD asm??
movdqu xmm1, xmmword ptr [r11+rax*4]        ; ??
movdqu xmm4, xmmword ptr [r10+rax*4]        ; ??

Why are there "+" and "*" operators shown instead of add and multiply ASM instructions to calculate the addresses? Surely the point of assembly is to completely break down the C++ in to only x86 instructions?

Это было полезно?

Решение

The first part of your question (why this is not an ADD instruction) and the second part (the *) have the same answer. The instruction here is trying to use the registers to form an index. This allows indexed access to the memory and is extremely useful in accessing logical arrays defined in the memory.

Two important points - the multiplicand cannot be any arbitrary value, it has to be one of 1, 2, 4 or 8 - this limits the direct array access only to elements up to 64 bits (qword) size. Had it allowed 16 or 32, a direct memory array of xmmword or ymmword would have been possible. The immediate offset that can be used is restricted to a maximum of 32-bit long number even in native 64-bit code - though usually, that should not cause so much a problem.

The second point is that this addition happens significantly faster than usual instruction based additions - so an instruction sequence like

shl rbx,1
mov rax, qword ptr [rsi+rbx]

is significantly slower than

mov rax,qword ptr [rsi+2*rbx]
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top