首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我怎么知道跳跃是绝对的还是相对的?

我怎么知道跳跃是绝对的还是相对的?
EN

Stack Overflow用户
提问于 2015-07-21 15:59:51
回答 3查看 8.1K关注 0票数 6

我正在学习装配测试和“位置独立代码”这一主题,我发现相对跳跃和绝对跳跃之间的区别令人困惑。我怎么知道是哪种跳跃?

我理解相对跳转是什么(与当前行的偏移量)。但是绝对跳跃是什么样子的呢?什么时候会发生?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-07-21 17:02:24

任何看似普通的jmp label都是相对的。

绝对跳跃看上去

  • jmp register
  • jmp [address]
  • jmp segment:absoluteaddr
  • jmp far [address]

任何跳远都是绝对的,任何间接的跳跃都是绝对的,因此组合(远,间接)也是绝对的。只有在必要时才会发生跳远(您必须更改cs,而不是call)。间接跳转用于函数指针、分支表(在某些情况下用于switch语句)、动态分派(虚拟方法)以及导入函数(通常您调用它们,但可能是尾调用)。

票数 9
EN

Stack Overflow用户

发布于 2015-07-21 17:42:34

根据体系结构和汇编程序或助记符,相对跳转可能无法与绝对跳转区分开来。

对于每个分支类型,有些体系结构有不同的助记符(由某些机器代码编码的指令的名称),另一些则具有相同的助记符。

通常是汇编程序负责根据目标指令的距离编写正确的跳转指令。

选择相对寻址是因为:

  • 它允许我们创建位置独立代码,这是有用的,但只有当我们也可以访问数据的事先知情同意方式。一般来说,在现代操作系统上,事先知情同意并不是必要的。 相反,感染向量和外壳代码充分利用了PIC代码,以及被移动的代码段(例如,IA32上带有固定向量的进程间中断需要一个例程位于一个精确的地址)。
  • 它大大减少了代码大小。相对跳跃可以使用一个操作数,只有8位!这是非常有用的系统与宽地址空间的比特术语。
  • 有些机器别无选择,例如,在RISC计算机中,指令长度是固定的,ARM中的32位是非拇指(和一些拇指),您不能在32位内编码operation_field + 32bit_operand

关于人的因素,我们在编程时通常处于“无论如何,它都不在乎”的状态,所以我们让汇编程序来选择。有时,当我们编写低级例程时,我们可能需要在内存中移动它们,并强制使用相对跳跃。有时,我们想跳转到一个固定的位置(例如,在0000h或0ff0h的重置向量),代码可能在内存中结束。

跳转的不完全示例

MIPS

beqbnebgtzbgezbltzblez都是相对跳跃

jjal是混合的,它们是绝对的,但是PC的高吞吐率是保持的。

jrjalr是绝对的(是间接的,即使用寄存器的值)。

有关更多信息,请参见这里

手臂

bblblx是相对的。

bxblx是绝对的。

如果你直接修改PC,这是一个绝对的跳转。

注意,直接指令是相对的,而间接指令不是相对的。这在RISC中非常常见。

有关更多信息,请参见这里

IA32e

jmp --这要么是相对的,要么是绝对的,取决于所使用的机器代码。更具体地说,跳跃可以是近的,也可以是远的。没有近乎绝对的直接跳跃。绝对近跳总是间接的(它们使用内存操作数或寄存器)。

跳远总是绝对的,可以是直接的(地址在指令操作数中)或者是间接的。

jmp label是一个近于跳跃的亲戚。

jmp [dest]jmp eax是近绝对(间接)跳跃。

jmp 0ffff0:0000h是绝对直接的。jump FAR [dest]是绝对间接的。

有关更多信息,您可以看到这里

票数 7
EN

Stack Overflow用户

发布于 2015-07-21 16:25:55

据我所知,当代码与位置无关时,使用了相对跳转(代码并不期望加载到特定的内存范围。例如,动态加载的dll库)。因此,这段代码中的所有分支都不能假设它们知道要跳转的确切地址,而是分支IP和目标IP之间的相对偏移量)。

绝对跳转得到目标的确切地址,当代码有静态地址空间时使用它。

希望能帮上忙

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31544052

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档