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?
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).