我正在学习装配测试和“位置独立代码”这一主题,我发现相对跳跃和绝对跳跃之间的区别令人困惑。我怎么知道是哪种跳跃?
我理解相对跳转是什么(与当前行的偏移量)。但是绝对跳跃是什么样子的呢?什么时候会发生?
发布于 2015-07-21 17:02:24
任何看似普通的jmp label都是相对的。
绝对跳跃看上去
jmp registerjmp [address]jmp segment:absoluteaddrjmp far [address]任何跳远都是绝对的,任何间接的跳跃都是绝对的,因此组合(远,间接)也是绝对的。只有在必要时才会发生跳远(您必须更改cs,而不是call)。间接跳转用于函数指针、分支表(在某些情况下用于switch语句)、动态分派(虚拟方法)以及导入函数(通常您调用它们,但可能是尾调用)。
发布于 2015-07-21 17:42:34
根据体系结构和汇编程序或助记符,相对跳转可能无法与绝对跳转区分开来。
对于每个分支类型,有些体系结构有不同的助记符(由某些机器代码编码的指令的名称),另一些则具有相同的助记符。
通常是汇编程序负责根据目标指令的距离编写正确的跳转指令。
选择相对寻址是因为:
operation_field + 32bit_operand!关于人的因素,我们在编程时通常处于“无论如何,它都不在乎”的状态,所以我们让汇编程序来选择。有时,当我们编写低级例程时,我们可能需要在内存中移动它们,并强制使用相对跳跃。有时,我们想跳转到一个固定的位置(例如,在0000h或0ff0h的重置向量),代码可能在内存中结束。
跳转的不完全示例
MIPS
beq,bne,bgtz,bgez,bltz,blez都是相对跳跃
j,jal是混合的,它们是绝对的,但是PC的高吞吐率是保持的。
jr,jalr是绝对的(是间接的,即使用寄存器的值)。
有关更多信息,请参见这里。
手臂
b,bl,blx是相对的。
bx,blx是绝对的。
如果你直接修改PC,这是一个绝对的跳转。
注意,直接指令是相对的,而间接指令不是相对的。这在RISC中非常常见。
有关更多信息,请参见这里。
IA32e
jmp --这要么是相对的,要么是绝对的,取决于所使用的机器代码。更具体地说,跳跃可以是近的,也可以是远的。没有近乎绝对的直接跳跃。绝对近跳总是间接的(它们使用内存操作数或寄存器)。
跳远总是绝对的,可以是直接的(地址在指令操作数中)或者是间接的。
jmp label是一个近于跳跃的亲戚。
jmp [dest],jmp eax是近绝对(间接)跳跃。
jmp 0ffff0:0000h是绝对直接的。jump FAR [dest]是绝对间接的。
有关更多信息,您可以看到这里。
发布于 2015-07-21 16:25:55
据我所知,当代码与位置无关时,使用了相对跳转(代码并不期望加载到特定的内存范围。例如,动态加载的dll库)。因此,这段代码中的所有分支都不能假设它们知道要跳转的确切地址,而是分支IP和目标IP之间的相对偏移量)。
绝对跳转得到目标的确切地址,当代码有静态地址空间时使用它。
希望能帮上忙
https://stackoverflow.com/questions/31544052
复制相似问题