1

I have an array a of 24 byte structs, arranged without padding so that struct 1 begins 24 bytes after struct 0 ((void*) &a[1] == ((void*) &a[0]) + 24.

rbx holds the index of the struct. I'd like to set rdi to a + rbx*24 and rsi to a + rbx*24 + 8. SIB does not allow multiplying by 24. How should I do this?

(x86, 64 bits, assembly).

SRobertJames
  • 8,210
  • 14
  • 60
  • 107
  • 5
    Use multiple instructions. E.g. use a `lea rbx, [rbx+2*rbx]` to multiply by 3 first, then do the remaining `8*rbx` to get to 24. – Jester Dec 01 '21 at 15:00
  • 2
    Address arithmetic is just arithmetic after all, and your CPU has a full complement of arithmetic instructions, so don't be afraid to use them. If you couldn't think of anything better, there would always be `imul rbx, 24`. But as Sep points out, you can in fact do better in this case. – Nate Eldredge Dec 01 '21 at 20:33
  • Note that ISO C doesn't define address math on `void*`. Probably you mean `(char*)`, or `(uintptr_t)`. As an extension, GNU C *does* let you do `24 + (void*)foo`, working like `char*` – Peter Cordes Dec 02 '21 at 01:56
  • You can ask a compiler: https://godbolt.org/z/jhbET64Ee – Erik Eidt Dec 02 '21 at 19:16

1 Answers1

4

You can set RDI and RSI without even changing the index in RBX.

lea  rsi, [rbx + rbx*2]    ; RSI = RBX * 3
lea  rdi, [a + rsi*8]      ; RDI = a + (RBX * 3) * 8
lea  rsi, [rdi + 8]        ; RSI = a + (RBX * 3) * 8 + 8

What's the purpose of the LEA instruction?

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • Why leave the `+8` for a separate instruction? If you can use `a` as an absolute signed disp32, you can use `a+8`. Oh, I see, because the question for some weird reason wanted both pointers actually materialized in separate registers. Perhaps as args for some function? Otherwise just use `[rdi]` and `[rdi+8]` addressing modes for accessing memory. Or even `[a + rsi*8]` and `[a * rsi*8 + 8]`, although that takes more space. – Peter Cordes Dec 02 '21 at 02:01
  • Yes, the pointers are each args to a function call. – SRobertJames Dec 02 '21 at 03:24