Home > Software engineering >  Forcing a JMP rel32
Forcing a JMP rel32

Time:12-13

If I do something like (dummy example):

jmp 1f
1: ret

on gcc/clang it generates a short relative jump because the label is near.

I'm curious, is it possible to force a JMP rel32 regardless of the label's distance?

CodePudding user response:

According to the GAS manual, section 9.16.8 "Jump instructions are always optimized to use the smallest possible displacements". This seems to imply there is no manual way to override it. There is an addr32 instruction prefix in 9.16.6 but it is only allowed in .code16. I cannot seem to find an option that would control the size of jmp offset in any "official" source.

However, according to this source marking the label you jump to as global will make the jmp instruction use a rel32 offset. I only managed to reproduce the behavior using clang though, GCC does not seem to work. Additionally, i cannot seem to find any more credible source for this behavior than the mentioned 15-year-old archived mailing list reply so i would not exactly call it "reliable". I assume it might go away unnoticed with some future update to clang/llvm-as.

For an example, following file test_asm.s:

.global main
main:
jmp lab
.global lab
lab: ret

compiled with clang test_asm.s on my machine results in:

000000000000111c <main>:
    111c:   e9 00 00 00 00          jmp    1121 <lab>

0000000000001121 <lab>:
    1121:   c3                      ret

Meanwhile, after removing the .global lab line the result is:

000000000000111c <main>:
    111c:   eb 00                   jmp    111e <lab>

000000000000111e <lab>:
    111e:   c3                      ret

For a reliable, although a tedious solution, you can always manually encode the jmp instruction to bytes and then input them using the .byte directive in place of the jmp <operand> mnemonic, as pointed out in the comments.

  • Related