The thing is that I cannot force gnu as
interpret jmp
as short
or near
, it constantly interprets it as far
.
For instance, the following code causes segfault
:
int main() {
asm volatile (
// ".intel_syntax noprefix\n\t"
// "jmp lbl%=\n\t"
// "lbl%=:\n\t"
"jmp *lbl%=(%%rip)\n\t"
"lbl%=:\n\t"
// ".att_syntax\n\t"
: : : );
return 0;
}
switching to the commented .intel_syntax
variant, it works perfectly well.
The only difference is that
jmp lbl%=
in intel
becomes eb 00
while
jmp *lbl%=(%%rip)
in att
becomes ff 25 00 00 00 00
how to force it in case of .att_syntax
to interpret it as short jump
?
CodePudding user response:
jmp *lbl
does an indirect jump -- loading the address from memory at lbl:
and jumping to that address. In this case it takes the 8 (code) bytes following this (the function epilog) and treats it as an address to jump to, thus causing a segfault.
For a simple PC relative jump, you want just jmp lbl
-- att syntax is the same as intel syntax here. There's no need for %rip
anything as all direct jumps are PC relative.