Search code examples
assemblyx86-64gnu-assembleratt

Why does AT&T jmp *bar assemble to machine code with a SIB byte? There's no register used in the instruction


I have this absolute indirect jump instruction on x86 machine:

ff 24 25 30 10 60 00

which was generated from:

jmp *bar

but I've got trouble with decoding second and third byte of it.

Second should be the Mod R/M field. So it translates to:

00 100 100

meaning:

00 - memory with no displacement (but it has the constant address, isn't this "displacement"?)

100 (dec. 4) - extended op. code (FF/4 => JMP r/m32)

100 - ?? SIB? but there is no register used in this instruction


P.S. some context:

Breakpoint 4, test () at test.s:13
13              jmp     *bar
(gdb) disassemble /r
Dump of assembler code for function test:
   0x000000000040051b <+0>:     c7 04 25 30 10 60 00 2f 05 40 00        movl   $0x40052f,0x601030
=> 0x0000000000400526 <+11>:    ff 24 25 30 10 60 00    jmpq   *0x601030
   0x000000000040052d <+18>:    87 c0   xchg   %eax,%eax
   0x000000000040052f <+20>:    c3      retq   
End of assembler dump.
(gdb) list
8               bar: .word 0x0
9       .text
10      test:
11      .LFB0:
12              movl    $label1, bar
13              jmp     *bar
14              xchg    %eax, %eax
15              label1:
16              ret
17      .LFE0:
(gdb) 

Solution

  • The operand bytes 24 25 indicate an absolute addressing mode with a 32 bit displacement, i.e. no base register and no index register. In 64 bit mode, this is distinct from the relative addressing mode with 32 bit displacement indicated by modr/m byte 25 (but in 32 bit mode it is not). If you want the latter addressing mode, write jmp *bar(%rip) in AT&T syntax.