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.
