【发布时间】:2011-01-11 08:48:27
【问题描述】:
作为链接器输入的文件称为对象文件。 链接器生成一个图像文件,然后加载器将其用作输入。
来自“Microsoft Portable Executable and Common Object File Format Specification”的简介
RVA(相对虚拟地址)。在图像文件中,项目的地址 在它被加载到内存后,与 图像文件的基地址 从中减去。项目的 RVA 几乎总是与其不同 在磁盘上的文件中的位置(文件 指针)。
在目标文件中,RVA 小于 有意义,因为内存位置 未分配。在这种情况下,RVA 将是一个部分内的地址 (本表稍后描述), 稍后应用重定位 在链接期间。为简单起见,一个 编译器应该只设置第一个 RVA 在每个部分归零。
VA(虚拟地址)。与 RVA 相同,不同之处在于 不减去图像文件。这 地址被称为“VA”,因为 Windows 创建一个独特的 VA 空间 对于每个进程,独立于 物理内存。对于几乎所有 目的,应考虑 VA 只是一个地址。 VA 不像 可预测为 RVA,因为 loader 可能不会在其位置加载图像 首选位置。
即使读了这篇文章,我仍然不明白。我有很多问题。任何人都可以用实际的方式解释它。请按照说明遵守Object File 和Image File 的术语。
我所知道的地址是这样的
- 在目标文件和图像文件中,我们都不知道确切的内存位置,所以,
- 汇编程序在生成目标文件时计算与
.data和.text部分相关的地址(用于函数名称)。 - 将多个目标文件作为输入的链接器会生成一个图像文件。在生成时,它首先合并每个目标文件的所有部分,并在合并时重新计算相对于每个部分的地址偏移量。而且,没有什么比全局偏移量更好的了。
如果我知道的有问题,请纠正我。
编辑:
阅读弗朗西斯的回答后,我清楚什么是物理地址、VA 和 RVA 以及它们之间的关系。
所有变量和方法的 RVA 必须在重定位期间由链接器计算。那么,(方法/变量的 RVA 值)==(它与文件开头的偏移量)?一定是真的。但令人惊讶的是,它不是。为什么会这样?
我在c:\WINDOWS\system32\kernel32.dll 上使用PEView 进行了检查,发现:
- RVA 和 FileOffset 直到 Sections 的开头都是相同的。(
.text是此 dll 中的第一部分)。 - 从
.text的开头到.data,.rsrc直到最后一节的最后一个字节 (.reloc) RVA 和 FileOffset 不同。 & 并且第一部分的第一个字节的 RVA 是“总是”显示为0x1000 - 有趣的是每个部分的字节在FileOffset中是连续的。我的意思是另一个部分从一个部分的最后一个字节的下一个字节开始。但是,如果我在 RVA 中看到同样的情况,那么这就是一节最后一个字节的 RVA 和下一节的第一个字节之间的巨大差距。
我的猜测:
-
所有,数据的字节数 在第一个之前(
.text这里) 部分“未”实际加载 进入过程的 VA 空间,这些 字节的数据只是用来 找到并描述这些部分。 它们可以称为“元节” 数据”。因为它们没有加载到 VA 过程空间。的使用 术语 RVA 也没有意义 这是
RVA == FileOffset这些字节的原因。 -
因为,
- RVA 术语仅对实际加载的字节有效 进入 VA 空间。
-
.text、.data、.rsrc、.reloc的字节就是这样的字节。 - 而不是从 RVA
0x00000启动 PEView 软件正在启动 来自0x1000。
我不明白为什么要进行第三次观察。我无法解释。
【问题讨论】:
标签: assembly linker loader portable-executable