x86-64 accessing element of array

636 views Asked by At

Hi I am a beginner in assembly language, is there a difference between movl (%rdi,%r12), %r10d and movl (%rdi,%r12,4), %r10d? I tried both of them and they both seem to do the same job-- saving the element of %rdi at %r12 position to %r10d. Is the 4 in the 2nd example really necessary?

1

There are 1 answers

4
Nate Eldredge On BEST ANSWER

Yes, they are different.

Suppose for example that %rdi = 0x12340000 and %r12 = 8. Then movl (%rdi,%r12), %r10d adds %r12 to %rdi to form an effective address, so you load a 32-bit dword from address 0x12340008. The 4 is the scale parameter of the SIB addressing mode; it causes %r12 to be multiplied by 4 before adding to %rdi, so with movl (%rdi,%r12,4), %r10d you load a 32-bit dword from address 0x12340020 instead.

See the GNU as manual: "If no scale is specified, scale is taken to be 1."

If you try it with an array defined like

int32_t foo[] = {1,3,5,7,9,11,13,15,17,19,21,23,25};

and %rdi contains the address of foo, with %r12 = 8 as above, then movl (%rdi,%r12), %r10d will load %r10d with the value 5, but movl (%rdi,%r12,4), %r10d will load it with the value 17. In other words, it is a question of whether you are treating %rdi as a count of bytes, or a count of 32-bit ints.

If they appear to work the same in your test, then either your test is buggy, or the two different addresses happen by coincidence to contain the same value, or your %r12 is zero, or your assembler is broken (unlikely).