1
votes

I am a beginner of C and assembly code who currently working on an assembly project. However, I meet some problem with the indirect jump instruction.

The jmp instruction line is:

4006a6: ff 24 c5 50 08 40 00    jmpq   *0x400850(,%rax,8)

When I go to 400850, the line is:

400850: ad                      lods   %ds:(%rsi),%eax
400851: 06                      (bad)  
400852: 40 00 00                add    %al,(%rax)
400855: 00 00                   add    %al,(%rax)
400857: 00 b3 06 40 00 00       add    %dh,0x4006(%rbx)
40085d: 00 00                   add    %al,(%rax)
40085f: 00 bc 06 40 00 00 00    add    %bh,0x40(%rsi,%rax,1)

Based on what I've learned, I should look at the address that stored in 400850 + 8 * rax, and jumps to that address to see instruction and do the specific operation. For example, if rax = 1, I should look at the address stored in 400858, but I cannot find 400858, and I also don't know what are the value such as "ab" mean, is it an address?

By the way, I believe this indirect jump represents an switch condition in the C code.

2
Start with 400857 and skip the first byte: b3 06 40 00, i.e. 004006b3 as a 32-bit little-endian (least significant first) word. It's often easier to look at a hex dump than disassembly when looking at data not code.Rup
@zx485: it's not code, it's data (pointers). You don't want to disassemble from 0x400858 either.Peter Cordes
0x400850 contains data, not code. Pointers to code, 8 bytes each. A switch/case statement is often compiled that way, each pointer in the table points to the case statement.Hans Passant

2 Answers

3
votes

jmpq *0x400850(,%rax,8) is an indirect jmp indexing into a table of jump targets. Yes, it's probably compiler-generated from a switch statement.


You used objdump -D instead of objdump -s, so the output breaks the hexdump up into chunks according to nonsensical decoding as x86-64 instructions, not into qword addresses.

The format is

starting   machine code            disassembly
address    hex byte(s)             (AT&T syntax)

400850:    ad                      lods   %ds:(%rsi),%eax

The byte(s) on one line go with the instruction. lods is a single-byte instruction with opcode 0xad, so the low byte of the qword at 0x400850 is 0xad

The hexdump is all there, but not every 8-byte chunk has a numbered label. Every byte has its own address; you just need to count from a preceding marked address to find the start of a chunk of data you want.


Or use objdump -s as recommended in assembly jmp to a line that doesn't exist to get a simple hexdump of each ELF section, split into uniform size chunks.

Or from inside GDB, an x command.

0
votes

This address 0x400850 is a pointer table, so it's something like: 400850: 00000000004006ad 400858: 00000000004006b3 400860: 00000000004006bc

rax is and index to the pointer table. you need to know the index and find the jump address from the table.