相对偏移量跳跃

时间:2012-07-20 20:36:37

标签: gcc assembly nasm intel

如何强制相对偏移的值?

我知道怎么做: jmp label_name

想做: jmp $ 0x01

感谢您的时间

4 个答案:

答案 0 :(得分:3)

你可以使用像

这样的相对跳跃
jmp $+5

它相对于跳跃的开始。

答案 1 :(得分:1)

语法问题...... Nasm将使用“$ + 5”,(G)使用“。+ 5”,并且可能还需要“$”(?)。我从原始标签中了解到,我们正在使用Nasm?然后“$ + 5”应该是正确的,但可能不会做你想要的。 asm语法是“jmp target”(或者对于Gas来说是“jmp $ target”),你会在反汇编中看到相同的东西......但仔细查看正在生成的字节。 “jmp”操作码后跟“目标距离”,而不是“目标”!如果你想编码“到目标的距离”,我认为你需要求助于“db 0xE8”(或适当的操作码),然后是“db(或dw或dd)0x ??” (我认为,气体的“.byte”或“.long”)。这可能不是你想要做的。重新考虑你的代码。

最佳, 弗兰克

答案 2 :(得分:1)

GAS和NASM没有语法来直接设置rel8或rel32位移,仅设置目标地址。 (例如jmp +0被解释为跳转到绝对地址0,或语法错误)。

您可以使用.byte / .long(GAS)或db(NASM和大多数其他非GAS x86汇编器)进行手动编码。请注意,相对分支位移是相对于分支指令的 end

    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相同,但用.byte.long代替dbdd


或者,使用语法描述相对于行首的地址

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

jmp  .+3                 # rel8 = +1      GAS

How does $ work in NASM, exactly?显示了以下示例的示例:手动编码分支以达到给定的目标,从目标地址中减去$(当前输出位置),并调整分支的长度。

在这里,我们需要考虑分支长度,以获得所需的相对偏移量编码,因为$ + x的参考点是指令的开始而不是结束。我们可以在标签的末尾:

   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.

这确实有效,我们从GAS获得了eb 7b

答案 3 :(得分:0)

这是我有趣的用法示例。

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

那样,一旦编译,它就会变成

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

这样跳转就在lea ebx,[esp]

之后着陆了