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?
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.
* 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
volatileafter asm and before the ()’s."