1

When objdump -S my_program, usually I can see the following indirect jmp instruction, which is typically used for switch/case jump table:

ffffffff802e04d3: ff 24 d5 38 2e 10 81 jmpq *-0x7eefd1c8(,%rdx,8)

How to understand the address -0x7eefd1c8? It means the table's base address is 0xffffffff802e04d3 - 0x7eefd1c8?

Also, how can I get -0x7eefd1c8 from ff 24 d5 38 2e 10 81?

WindChaser
  • 960
  • 1
  • 10
  • 30
  • possible duplicate of [What does this x86-64 assembly line do?](http://stackoverflow.com/questions/9223756/what-does-this-x86-64-assembly-line-do) – myaut Mar 05 '15 at 07:38
  • That question does not answer: How to get `-0x7eefd1c8` from `ff 24 d5 38 2e 10 81`. It is a decoding issue. – WindChaser Mar 05 '15 at 15:54

1 Answers1

3

decoding issue

Than you have to look at Intel Development Manuals

  • ff is JMP opcode (Jump near, absolute indirect) [1]
  • 24 is a ModR/M byte [2] which means that SIB byte goes after it (JMP opcode has only one operand, so register field is ignored)
  • d5 is a SIB byte [2] which means that disp32 goes after that, Scale = 8 and Index = %rdx (in 32-bit mode, Index should be %edx) with no base.
  • 38 2e 10 81 is a 4-byte disp32 operand. If you encode it as double word, you will get 0x81102e38 note that highest bit is set to 1. It is a sign bit meaning that value is encoded in Two’s Complement Encoding [3].

Converting from two's complement gives us expected number:

>>> print hex(0x81102e38 - (1 << 32))
-0x7eefd1c8 

When processor executes that instruction in 64-bit mode, it reads 8 bytes from 0xffffffff81102e38 + (%rdx * 8) (original number is sign-extended) and puts that quad word into %rip [4].

References to manuals:

  1. Vol.2A, section 3.2 INSTRUCTIONS (A-M), page 3-440
  2. Vol 2, section 2.1.5 Addressing-Mode Encoding of ModR/M and SIB Bytes, pages 2-6..2-7
  3. Vol 1, section 4.2.1.2 Signed Integers, page 4-4
  4. Vol 2, section 2.2.1.3 Displacement, page 2-11
myaut
  • 11,174
  • 2
  • 30
  • 62