1

I'm trying to understand the LEA assembly instruction. I'm using lldb, and at this point in execution of a program, the memory is as follows:

->  0x100000f12 <+130>: lea    rdi, [rip + 0x82]  
(lldb) register read rip
     rip = 0x0000000100000f12

I would expect after this instruction is run, rdi should contain:

hex(0x0000000100000f12 + 0x82) = '0x100000f94'

But instead, rdi contains:

(lldb) register read rdi
    rdi = 0x0000000100000f9b

Which is 7 offset of what was expected:

0x100000f9b - (0x0000000100000f12 + 0x82) = 7

I'm guessing the 7 has to do with the the size of a byte, but I would like to know more concretely what exactly is going on.

Jester
  • 56,577
  • 4
  • 81
  • 125
MathStudent
  • 310
  • 2
  • 12
  • 5
    The 7 is the size of the instruction. The `rip` value already points past the instruction when it's used. See section _2.2.1.6 RIP-Relative Addressing_ in the _Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 2: Instruction Set Reference, A-Z_ which says "address is formed by adding displacement to the 64-bit RIP of the **next** instruction." – Jester Nov 23 '17 at 17:08
  • OK, so at any given time rip does point to the next instruction that will be executed. But this means rip is incremented prior to that instruction being executed, and at the time of execution rip now contains the address of the next instruction, and this updated value is what is used for the computation (0x....f19 + 0x82?) – MathStudent Nov 23 '17 at 17:19
  • 2
    Yes, that is correct. – Jester Nov 23 '17 at 17:29
  • This is true for every processor I have worked with. If there are 7 bytes of instructions to read why *wouldn't* the instruction pointer be incremented? – Weather Vane Nov 23 '17 at 17:46
  • 2
    @WeatherVane on SPARC it points to current instruction, and on ARM it even points two past the current :) – Jester Nov 23 '17 at 17:57
  • @Jester hmmm thank you. – Weather Vane Nov 23 '17 at 17:59
  • It used to be the `ip` was already used by other unit of CPU to pre-fetch next instruction while the previous one (already fetched+decoded) was being executed. With modern x86 it's backward compatibility thing (the pre-fetch is already several instructions ahead, following also branches by branch prediction and return address predictions, etc... so the "address of next instruction" is artificially provided as needed.. or rather it's like the `rip` is artificially slowly updated just ahead of execution, while prefetch is using different shadowed+speculative `rip`). – Ped7g Nov 24 '17 at 02:17

0 Answers0