首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么x86跳转/呼叫指令使用相对位移而不是绝对目的地?

为什么x86跳转/呼叫指令使用相对位移而不是绝对目的地?
EN

Stack Overflow用户
提问于 2017-09-12 20:22:00
回答 1查看 5.2K关注 0票数 5

我正在学习8086,有一个特别的问题困扰着我,我还没有找到令人满意的答案。

我知道CPU按顺序执行代码,如果想更改代码流,我们希望IP指向我们感兴趣的代码所在的新/旧地址。

现在,我的问题是,为什么当我们遇到跳转指令时,我们(我的意思是CPU)不去用标签对应的地址更新IP?

当我们遇到跳转指令时,有什么必要增加到IP中的位移?

照我的想法

  1. 计算位移(即跳转标签到跳转后下一条指令的距离)和
  2. 然后接受第二代人的赞美
  3. 它最终被添加到IP中,以便IP指向标签所指向的地址/指令。

对我来说,这听起来像是更多的工作,而不是只是更新IP与相应的地址标签。但是,我相信这样做一定有原因,只是我不知道而已。

在8086,这种设计选择的原因是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-09-14 06:32:09

您大大高估了解码相对跳跃的CPU复杂度的成本。

  1. 计算位移(即跳转标签到跳转后下一条指令的距离)
  2. 然后接受第二代人的赞美

机器代码必须包含步骤2(有符号整数相对位移)的结果,所以所有这些都是在组装时完成的。在汇编程序中,减去两个整数地址已经给出了你需要的有符号2的补码位移。

使用相对位移有真正的好处,因此仅仅为了简化汇编程序的编写而使ISA变得更糟是没有任何意义的。您只需要编写一次汇编程序,但是机器上运行的一切都得益于更紧凑的代码和位置独立性。

相对分支位移是完全正常的,并且在大多数其他架构中也使用(例如ARM:https://community.arm.com/processors/b/blog/posts/branch-and-call-sequences-explained,其中固定宽度的指令使得直接绝对分支编码无论如何都不可能)。--它将使8086成为而不是的单数,使用相对分支编码.

update:也许并不完全是奇怪的。MIPS使用rel16 << 2进行beq / bne (MIPS指令固定在32位宽且始终对齐)。但是对于无条件的j (跳转)指令,它是有趣的是,它使用了伪直接编码。。它保持了PC机的高4位,直接用指令中编码的值代替PC[27:2]位。(同样,程序计数器的低2位总是0。)因此,在相同的地址空间的1/16范围内,j指令是直接跳转,不提供与位置无关的代码。这适用于jal (跳转链接= call)、使PIC代码中的函数调用效率降低 :( Linux以前需要PIC二进制文件、但显然现在不是 (但共享库仍然必须是PIC) )。

当CPU运行eb fe时,它所要做的就是将位移添加到IP中,而不是替换IP。由于非跳转指令已经通过增加指令长度来更新IP,加法器硬件已经存在.

请注意,符号延伸 8位位移到16位(或32位或64位)在硬件上是微不足道的:2的补充符号扩展只是复制符号位,这不需要任何逻辑门,只是连接一位到其余。(例如,0xfe变成0xfffe,而0x05变成0x0005。)

8086非常强调代码密度,提供了许多常用指令的简短形式。这是有意义的,因为代码提取是8086中最重要的瓶颈之一,所以较小的代码通常是更快的代码。

例如,存在两种形式的相对jmp,一种是rel8 (短),另一种是rel16 (近)。(在后来的CPU中引入的32位和64位模式中,E9操作码是jmp rel32而不是rel16,但EB仍然是jmp rel8,因为函数内的跳转通常在-128/+127之内)。

但是call并没有什么特别的缩写,因为它在大多数情况下都不会有多大用处。那么,它为什么还要考虑相对位移而不是绝对位移呢?

x86确实有绝对的跳跃,但只适用于间接的或远的跳跃。(转到不同的代码段)。例如,EA操作码是“跳远、绝对、以操作数表示的地址”。

要做一个绝对的近距离跳跃,只需mov ax, target_label / jmp ax。(或者用MASM语法,mov ax, OFFSET target_label)。

相对位移是位置无关的

对这个问题的评论提出了这一点。

考虑一个机器代码块(已经组装好了),其中有一些跳转。如果您将整个块复制到不同的起始地址(或更改CS基本地址,以便在与段的偏移量不同的情况下访问同一个块),那么只有相对跳转才能继续工作。

要使标签+绝对地址解决同样的问题,必须用不同的ORG指令重新组装代码。显然,当你用一个远jmp改变CS时,这是不可能发生的!

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

https://stackoverflow.com/questions/46184755

复制
相关文章

相似问题

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