1

Given this code:

int main(void)
{
    __asm volatile ("jmp %eax");

    return 0;
}

32-bit TCC will complain with:

test.c:3: error: unknown opcode 'jmp'

but the 64-bit version will compile just fine.

What's the problem with the 32 bit code?

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
hauzer
  • 258
  • 3
  • 12
  • @Martin James: From [here](http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#ss5.4): "If our assembly statement must execute where we put it, (i.e. must not be moved out of a loop as an optimization), put the keyword `volatile` after asm and before the ()’s." – hauzer Aug 29 '13 at 22:38

1 Answers1

1

The solution is to simply add a star (*) before the register, like this:

__asm volatile ("jmp *%eax");

I'm not exactly sure what the star means. According to this SO post:

The star is some syntactical sugar indicating that control is to be passed indirectly, by reference/pointer.

As for why it works with 64-bit TCC, I assume that it's a bug; 64-bit GCC complains with Error: operand type mismatch for 'jmp', as it should.

Community
  • 1
  • 1
hauzer
  • 258
  • 3
  • 12
  • The `*` means it's an indirect jump, setting IP/EIP/RIP = value from register or memory, rather than `jmp rel32` to a label address. TCC 0.9.27 still has this bug; I checked with `objdump -d` and it emits `ff e0 jmp *%rax` – Peter Cordes Apr 17 '19 at 20:40