1
votes

How can I force the value of the relative offsets?

I know how to do: jmp label_name

Would like to do: jmp $0x01

4
TL;DR of the answers: jmp . + 3johnchen902

4 Answers

4
votes

You can use a relative jump like

jmp $+5

It relative to the start of the jump.

1
votes

Syntax issue... Nasm would use "$ + 5", (G)as would use ". + 5", and might need a "$" as well(?). I understand from the original tag, that we're using Nasm? Then "$ + 5" should be correct, but probably won't do what you want. The asm syntax would be "jmp target" (or "jmp $target" for Gas?), and you'll see the same thing in a disassembly... but look closely at the bytes being generated. The "jmp" opcode is followed by "distance to target", not "target"! If you want to code "distance to target", I think you'll need to resort to "db 0xE8" (or appropriate opcode) followed by "db (or dw or dd) 0x??" (".byte" or ".long" for Gas, I think). This probably isn't what you want to do. Re-think your code.

Best, Frank

1
votes

GAS and NASM don't have syntax to set the rel8 or rel32 displacement directly, only the target address. (e.g. jmp +0 is interpreted as a jump to absolute address 0, or a syntax error).

You can encode it manually with .byte / .long (GAS) or db (NASM and most other non-GAS x86 assemblers). Note that the relative branch displacement is relative to the end of the branch instruction.

    db  0xEB, 0x01    ; jmp short +1   over the 1-byte nop
    nop                   
 jump_target:    
    db  0xE9
        dd    -5     ;  jmp near -5    also jump backwards to jump_target, i.e. to itself

(GAS would be identical but with .byte and .long instead of db and dd)


Or, use syntax for describing an address relative to the start of the line

jmp short  $+3           ; rel8 = +1      NASM, forcing the jmp size to 2 bytes

jmp  .+3                 # rel8 = +1      GAS

How does $ work in NASM, exactly? shows an example of manually encoding a branch to reach a given target, subtracting $ (the current output position) from the target address, and adjusting for the length of the branch.

Here we need to take the branch length into account to get the the desired relative offset encoded, because our reference point for $ + xis the start, not end of the instruction. We could put a label at the end:

   jmp  .rel_anchor + 123       ; rel8= +123   NASM local label
.rel_anchor:

   jmp  1f + 123; 1:            # GAS local label on the same line but a separate statement
 1:                             # It might be more readable to put the label here.

This does actually work, we get eb 7b from GAS.

0
votes

Here is an example usage I made for fun.

BITS 32
segment .text
global _start
_start:
    jmp tmp
    PUSH 0x68732f
    PUSH 0x6e69622f
    LEA EBX,[ESP]
    ; ...
_jumpstop:
    tmp equ ($ - _start)

That way once it is compiled it becomes

00000000  E90D000000        jmp 0x12
00000005  682F736800        push dword 0x68732f
0000000A  682F62696E        push dword 0x6e69622f
0000000F  8D1C24            lea ebx,[esp]

So that the jump lands immediately after the lea ebx,[esp]