绝对地址转移与相对近地址转移

绝对地址转移与相对近地址转移

Content #

处理器取指令、执行指令是依赖于段寄存器CS 和指令指针寄存器IP 的,8086 处理器取指令时,把CS 的内容左移4 位,加上IP 的内容,形成20 位的物理地址,取得指令,然后执行,同时把IP 的内容加上当前指令的长度,以指向下一条指令的偏移地址。但是,一旦处理器取到的是转移指令,情况就完全变了。

绝对地址转移 #

jmp 指令有多种格式。最典型地,它的操作数可以是直接给出的段地址和偏移地址,这称为绝对地址。比如:

jmp 0x5000:0xf0c0

此时,要转移到的目标位置是非常明确的,即,段地址为0x5000,段内偏移地址为0xf0c0。在这种情况下,指令的操作码为0xEA,故完整的机器指令是:

EA C0 F0 00 50

处理器执行时,发现操作码为0xEA,于是,将指令中给出的段地址传送到段寄存器CS;将偏移地址传送到指令指针寄存器IP,从而转移到目标位置处接着执行。

相对近地址转移 #

jmp 指令使用关键字“near”,表示相对近地址转移,其操作数是以标号(infi)的形式给出。

infi: jmp near infi                 ;无限循环

jmp near infi 的机器指令格式和它的汇编指令格式完全不同,颇具迷惑性。它是一个3 字节指令,操作码是0xE9,后跟一个16 位(两字节)的操作数。编译后的机器码为:

E9 FD FF

需要注意的是,该操作数(FD FF)并非目标位置的偏移地址,而是目标位置相对于当前指令处的偏移量(以字节为单位)。下面就来看偏移量的计算方法:目标位置就是当前指令自己的位置,间隔的长度为0。再用0 减去当前指令长度3,这是一个负数。 0xFFFD 等于十进制数65533,也就是这条指令需要的操作数负3。

编译器如何区分这两种不同的转移方式? #

当它看到JMP 之后是一个绝对地址,如0xF000:0x2000 时,它就知道应当编译成使用操作码0xEA 的直接绝对转移指令。

相反地,如果它发现JMP 之后是一个标号,那么,它就会编译成使用操作码为 0xE9 的相对转移指令。关键字“near”不是最主要的,它仅仅用于指示相对量是16 位的。

Viewpoint #

From #