逻辑地址生成是由CPU还是编译器完成?

问题描述 投票:0回答:1

我很困惑,CPU 生成程序的逻辑地址还是编译器在 CPU 的帮助下完成?而这一代又是在什么时候进行的呢? 有人可以解释一下到底发生了什么吗?

逻辑地址是程序运行时由CPU生成的。

我在几个网站上找到了这个,我知道CPU获取这个逻辑地址并在MMU的帮助下将其转换为物理地址,但我的疑问是逻辑地址是如何生成的?

我发现了这个问题的许多不同答案,有些人说“生成”这个术语用得不好,而另一些人只是解释逻辑地址如何提供虚拟化。

关于逻辑地址起源的简短解释将不胜感激,谢谢!

operating-system cpu-architecture memory-address
1个回答
0
投票

具体细节取决于CPU架构、编译器、链接器、操作系统和配置。因此,以下内容是简化的。

除非在内核等特殊情况下或目标系统没有 MMU 时,否则编译器和链接器处理逻辑地址。因此,当下面说“地址”时,我指的是“逻辑地址”。

编译器很少静态地知道某个东西的地址。我无法举出例子。

当代码引用某些全局变量或函数时,编译器将在重定位表中创建一个条目,稍后链接器将使用该条目来填充地址,这个过程称为“重定位”。如今,编译器和链接器通常配置为生成“位置无关代码”,这意味着生成的代码将独立于代码地址正常工作。如果引用代码和引用的东西都可以加载到非固定地址,则编译器无法在代码中放置固定地址。 我不会详细介绍位置无关代码的工作原理,但我会给出一个简单的例子。如果您的程序包含一个调用另一个函数(被调用者)的函数(调用者),则链接器将输出包含这两个函数的代码(如果我们假设被调用者未内联到调用者中)。代码将连续加载到内存中,因此链接器知道调用指令和被调用者开头之间的区别。在这种情况下,调用指令可以通过使用相对于程序计数器的地址来引用被调用者。当CPU执行call指令时,它会将当前程序计数器以及call指令与被调用者开头的差值相加,生成被调用者的地址。 存储在堆栈上的变量通常由相对于堆栈指针的地址来引用。动态分配的对象的地址由动态内存分配器生成。

总而言之,地址生成是通过编译器、链接器和CPU的交互来完成的。只有在极少数情况下,编译器才能单独生成地址。由于位置无关代码是当今的标准,因此链接器通常也不会生成地址。地址通常由 CPU 在运行时生成,但基于来自编译器和链接器的信息。

© www.soinside.com 2019 - 2024. All rights reserved.