我怎样才能知道跳是绝对的还是相对的?(How can I tell if jump is absol

2019-10-24 01:56发布

我正在学习在组装测试,并在“位置无关码”的问题,我找到一个相对跳转和绝对跳转混乱之间的差异。 我如何才能知道什么样的跳它是什么?

我明白了一个相对跳转是什么(从当前行的偏移量)。 但什么是绝对跳转样子? 它什么时候发生?

Answer 1:

任何看起来像只是普通的jmp label是相对的。

绝对跳跃的样子

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

任何远跳是绝对的,任何间接跳转是绝对的,因此组合(远,间接的)也绝对。 远跳只在必要时(你必须改变发生cs ,它不是一个call )。 间接跳转用于函数指针,分支表(在某些情况下,用于switch语句),动态调度(虚方法),并可能进口功能(通常是你给他们打电话,但也许这是一个尾调用)。



Answer 2:

根据架构和汇编或助记符相对跳转可以是绝对的没有区别。
一些架构具有用于每个分支型不同助记符(由一些机器代码编码的指令的名称),其他具有相同的助记符。

通常,它是需要编写根据目标指令的距离权跳转指令的关心汇编。
相对寻址是首选,因为:

  • 它允许我们创建位置无关的代码,这是有用的,但前提是我们还可以在PIC的方式访问数据。 一般现代OS PIC是不是必需品。
    感染矢量和的shellcode代替采取的PIC代码很大的优势,因为代码dinamically移动部分沿(例如进程间中断与IA32固定矢量需要的例程是在精确的地址)。
  • 它巨大的减少代码大小。 相对跳跃可以使用只要8位的操作! 这是系统在长期的比特宽的地址空间是非常有用的。
  • 有些机器别无选择,在RISC计算机,例如指令长度是固定的,在ARM是32位非拇指(有的大拇指),你不能代码operation_field + 32bit_operand在32位!

人的因素,我们通常是在国家“ 这种或那种方式,它并不关心 ”节目,所以当我们让汇编选择。 有时当我们写低级程序,我们可能需要将其移动在内存中,强制使用相对跳跃。 有时我们希望(位于0000h或0ffff0h例如复位向量)跳转到一个固定位置的地方的代码可以在存储器中结束。


跳跃的一些不完整的例子

MIPS

beqbnebgtzbgezbltzblez都是相对的跳跃

jjal是那种复杂的,他们是绝对的,而PC的高四位保持。

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

欲了解更多信息,请参见这里 。

bblblx是相对的。

bxblx是绝对的。

如果修改了PC直接是绝对跳转。

请注意,采取立即数的指令,而间接一个都没有怎么是相对的。 这是很常见的RISC。

欲了解更多信息,请参见这里 。

IA32E

jmp这是相对或绝对取决于所使用的机器代码。 更具体地跳跃可近或远。 没有接近绝对直接跳转。 绝对附近跳跃总是间接的(他们使用的内存数或寄存器)。
远跳转总是绝对的,可以是直接的(该地址是在指令操作数)还是间接的。

jmp label是近亲跳。
jmp [dest]jmp eax是接近绝对(间接)跳跃。
jmp 0ffff0:0000h远绝对直接。 jump FAR [dest]远绝对是间接的。

欲了解更多信息,你可以看到在这里 。



Answer 3:

从我记得,当代码是位置独立于所使用的相对跳跃(代码不期望被加载到特定存储器范围。对于被动态加载实例dll库)。 因此,在这段代码中所有的分支不能假设他们知道跳的确切地址,但分支机构IP和目标IP)之间的相对偏移。

绝对转移获得目标的准确地址,当代码有静态地址空间,它的使用。

希望能帮助到你,



文章来源: How can I tell if jump is absolute or relative?