【问题标题】:How to use relative jumps?如何使用相对跳跃?
【发布时间】:2012-06-22 17:14:49
【问题描述】:

我有以下关于相对跳跃的问题:

  1. 我知道JMP SHORT <displacement> 会相对于当前PC 跳转到<displacement> 字节。对吗?
  2. 是不是汇编器会自动生成一个相对跳转的操作码?即当我只写JMP <label>时,如果该标签位于当前PC的128字节以内,它会产生相对跳转?
  3. 如果我确实想使用JMP SHORT <displacement>,计算位移的正确方法是什么?通过检查列表文件并计算偏移量?

【问题讨论】:

    标签: assembly nasm x86


    【解决方案1】:

    每个汇编器(程序)和汇编器的每个版本都可以选择默认为长或短。因此,我不会寻找所有汇编程序默认为一件事的笼统声明。如果好奇,请尝试一下,看看会发生什么。

    使用 x86 和可变长度指令,简单地编写位移代码将非常棘手,必须提醒自己永远不要接触跳转和目标之间的代码。

    是的,我首先让汇编器使用标签对指令进行编码,然后获取指令集参考手册和带有地址的反汇编,并弄清楚如何计算位移。如果汇编器允许您自己设置位移,这可能是汇编器特定的东西,并且您需要知道它可能需要该位移的单位。 x86 可能是字节,但是固定字长指令集可能必须以指令为单位而不是字节来表示。或字节不是指令,所以我会使用位移然后再次反汇编以查看它计算了正确的指令。

    【讨论】:

      【解决方案2】:

      假设汇编器自动使用短编码或普通编码。乍一看,如果可能,总是切换到短编码似乎没问题,但实际上有可能这样做,以便必须再次将某些其他分支更改为长编码。

      例如(未经测试或其他任何东西,只是为了得到想法):

        jmp _skip          ; relative offset depends on
                     the size of "other code", which may include other jumps
        ; other code
      _skip:
      

      所以你不能做一个“前向”传球来确定尺寸 - 当你在那个跳跃时,你还不知道它是否适合,因为你还没有决定如何处理还有其他的跳跃。

      那么倒退? (未经测试或其他任何东西,只是为了得到这个想法)

        .fill 124
        jmp _somewhere     ; 2 bytes, or 5?
        jmp _quiteFarAway  ; relative offset is either 130 or 127
        .align 256
      _quiteFarAway:
      

      不,也不能向后传递,在决定跳转到 _quiteFarAway 的编码时,您还不知道它是否适合,因为您还没有决定如何处理其他跳转。

      做到你的第 2 点很难,有很多不同的方法可以解决这个问题。例如采用显式“短”修饰符、显式“长”修饰符、进行安全猜测并最终得到在极少数情况下不需要的长版本等。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-07
        • 1970-01-01
        • 2015-10-11
        • 1970-01-01
        • 1970-01-01
        • 2019-05-30
        • 2021-04-21
        • 1970-01-01
        相关资源
        最近更新 更多