Assembly 我如何判断跳跃是绝对的还是相对的?

Assembly 我如何判断跳跃是绝对的还是相对的?,assembly,nasm,x86-16,instruction-set,position-independent-code,Assembly,Nasm,X86 16,Instruction Set,Position Independent Code,我正在学习汇编测试,在“位置无关代码”这一主题中,我发现相对跳转和绝对跳转之间的区别令人困惑。 我怎么知道这是什么样的跳跃呢 我知道什么是相对跳跃(相对于当前行的偏移)。 但是绝对跳跃是什么样子的呢?什么时候发生的?据我回忆,当代码是位置独立的(代码不希望加载到特定的内存范围。例如动态加载的dll库)时,使用相对跳转。因此,此代码中的所有分支都不能假定它们知道要跳转的确切地址,而是知道分支IP和目标IP之间的相对偏移量) 绝对跳转获取目标的确切地址,当代码具有静态地址空间时使用绝对跳转 希望有帮

我正在学习汇编测试,在“位置无关代码”这一主题中,我发现相对跳转和绝对跳转之间的区别令人困惑。 我怎么知道这是什么样的跳跃呢

我知道什么是相对跳跃(相对于当前行的偏移)。
但是绝对跳跃是什么样子的呢?什么时候发生的?

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

绝对跳转获取目标的确切地址,当代码具有静态地址空间时使用绝对跳转


希望有帮助,

任何看起来像普通的
jmp标签的东西都是相对的

绝对跳跃看起来像

  • jmp寄存器
  • jmp[地址]
  • jmp段:绝对地址
  • jmp far[地址]

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

根据体系结构和汇编程序或助记符,相对跳转可能无法与绝对跳转区分。
有些体系结构对于每个分支类型具有不同的助记符(由某些机器代码编码的指令名称),而另一些体系结构具有相同的助记符

通常是汇编程序根据目标指令的距离编写正确的跳转指令。
首选相对寻址,因为:

  • 它允许我们创建与位置无关的代码,这很有用,但前提是我们还可以以PIC方式访问数据。一般来说,在现代操作系统上使用PIC并不是必须的。
    相反,感染向量和外壳代码极大地利用了PIC代码以及动态移动的代码段(例如,IA32上带有固定向量的进程间中断要求例程位于精确地址)
  • 它极大地减少了代码大小。相对跳跃可以使用一个8位的操作数!这在具有宽地址空间的系统中非常有用
  • 有些机器别无选择,例如,在RISC计算机中,指令长度是固定的,在ARM中,非Thumb(和一些Thumb)的指令长度是32位,并且您不能在32位中编码
    操作字段+32位操作数
关于人为因素,我们在编程时通常处于“这样或那样,它不在乎”的状态,所以我们让汇编程序选择。有时,当我们编写低级例程时,我们可能需要在内存中移动它们,并强制使用相对跳跃。有时,我们希望跳转到一个固定的位置(例如0000h或0ffff0h处的重置向量),代码可能会在内存中结束


一些不完整的跳跃示例

MIPS
beq
bne
bgtz
bgez
bltz
blez
都是相对跳跃

j
jal
是混合的,它们是绝对的,但保持了PC的高字节

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

有关详细信息,请参阅

手臂
b
bl
blx
是相对的

bx
blx
是绝对值

如果你直接修改电脑,这是一个绝对的跳跃

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

有关详细信息,请参阅

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

jmp-label
是一个近跳跃的相对物。
jmp[dest]
jmp eax
几乎是绝对(间接)跳跃。
jmp 0ffff0:0000h
是绝对直接的。
跳远[dest]
是绝对间接的


有关更多信息,请参见。

对于x86等体系结构,根据工具链,唯一知道的方法是分解最终二进制文件,链接器可以/将根据需要更改跳转,即使对于arm和其他应用程序,链接器也可能修改那里的代码,或者添加额外的代码来制作一个蹦床,从而产生从编译器生成的任何内容转换为所需内容的总体效果。依赖于体系结构和工具链的旧链接器只会给出一个错误,有些仍然会,但是gnu已经开始添加更多的代码,试图更混淆OP?使用8086这样的标签,用户lolu不会从您的高质量答案中学到多少。