-4

What does the 40 in movq 40(%rdi), %rax mean?

I see that the value (in other instructions automatically generated by gcc) is always a positive multiple of 8 (ie. 8, 16, 24, 32, ...)

It is also always surrounded by ()

I also know that the () means the address of.

But what does the 40 in the example mean?
When I try changing it, it even allows non-multiples of 8 (eg. 2, 3, 7, -3, -28) and compiles fine.


Some sample values by changing 40 to something else:

movq    $1, (%rdi)
movq    0(%rdi), %rax

%rax: 2


movq    $1, (%rdi)
movq    1(%rdi), %rax

%rax: 72057594037927937


movq    $1, (%rdi)
movq    2(%rdi), %rax

%rax: 281474976710657


movq    $1, (%rdi)
movq    8(%rdi), %rax

%rax: 2


movq    $1, (%rdi)
movq    16(%rdi), %rax

%rax: 4


movq    $1, (%rdi)
movq    24(%rdi), %rax

%rax: 140730710821713


movq    $1, (%rdi)
movq    32(%rdi), %rax

%rax: 2761649059213359105

Jester
  • 56,577
  • 4
  • 81
  • 125
sviamwvnb
  • 139
  • 1
  • 6
  • `movq 32(%rdi), %rax` adds 32 to the contents of `%rdi` and uses that as the address of the data to move. It's an offset. This should be described in any assembly reference. Did you read the documentation? Look up "addressing modes" for x64. – lurker Jan 07 '18 at 01:51
  • I'm not sure I understand. `movq $1, %rdi` then `movq 32(%rdi), %rax` results in a seg fault when run – sviamwvnb Jan 07 '18 at 01:54
  • It does, because it tries to use `32+1=33` as an address, and that is not typically valid. – Jester Jan 07 '18 at 01:55
  • You application is not allowed to access memory location 33 on your system. So you get a segmentation fault. Apps cannot access arbitrarily any memory location they want to. – lurker Jan 07 '18 at 01:58
  • I see. So it's basically the same as pointers in C in which we add the offset – sviamwvnb Jan 07 '18 at 01:59
  • More or less. For example, if you have an array `char a[10]` and the address of `a` is in `%rdi`, then yes you can access `a[7]` by `7(%rdi)`. That's just a simple example. Arrays of larger types become more complex, and the compiler may or may not use that mechanism to reference an array element. – lurker Jan 07 '18 at 02:00
  • @Jester Wait. So `$1` in `movq $1, %rdi` isn't the value 1, but address location 0x01? – sviamwvnb Jan 07 '18 at 02:01
  • The value 1 in `%rdi` is *address* 0x01 because `(%rdi)` tells the CPU to reference the data at the location whose address is in `%rdi`. Or in this case, more precisely, referencing `32(%rdi)` tells the CPU to reference the data at the location whose address is 32 + the value in `%rdi` which totals 33, also an invalid address. You really need to read up on x86 or x64 *addressing modes* as I suggested before. – lurker Jan 07 '18 at 02:02
  • Oh. So `(%rdi)` isn't the address of `%rdi`, but the address of the value of `%rdi` – sviamwvnb Jan 07 '18 at 02:04
  • Registers on x86 don't have addresses themselves. – Jester Jan 07 '18 at 02:12
  • 1
    Wait, are you reading no book/tutorial, and just looking at compiler output to guess what assembly does? That path will be lot more twisted than you can imagine, assembly language is lot more "what HW engineers did" than "what it may look and would make sense in programming language", so without reading the proper books and documentation you have zero chance to decipher some of the instructions behaviour, like for example `mul ebx` or `div ebx` is completely non-guessable (yet people try, and then they post new SO question about it like every week or so). – Ped7g Jan 07 '18 at 09:51

1 Answers1

1

40(%rdi) in AT&T syntax is [rdi + 40] in NASM syntax. It's a memory operand where the effective address is 40 + RDI. 0(%rdi) is the same thing as (%rdi): no displacement. See Referencing the contents of a memory location. (x86 addressing modes).

Your first example stores an 8-byte 1 to (%rdi) and then reloads from the same address. But you claim you got 2, so you did something wrong there.

Your other example are storing and then loading from a partially-overlapping location like rdi+2 or not-overlapping like rdi+16. In the latter case, the load result doesn't depend at all on the store.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847