macos - 链接器在链接时是否生成绝对虚拟地址
问题描述
假设一个简单的 hello world in C
,使用编译gcc -c
到目标文件并使用objdump
将如下所示进行反汇编:
_main:
0: 55 pushq %rbp
1: 48 89 e5 movq %rsp, %rbp
4: c7 45 fc 00 00 00 00 movl $0, -4(%rbp)
b: c7 45 f8 05 00 00 00 movl $5, -8(%rbp)
12: 8b 05 00 00 00 00 movl (%rip), %eax
如您所见,内存地址是0, 1, 4, ..
等等。它们不是实际地址。
链接目标文件并反汇编它看起来像这样:
_main:
100000f90: 55 pushq %rbp
100000f91: 48 89 e5 movq %rsp, %rbp
100000f94: c7 45 fc 00 00 00 00 movl $0, -4(%rbp)
100000f9b: c7 45 f8 05 00 00 00 movl $5, -8(%rbp)
100000fa2: 8b 05 58 00 00 00 movl 88(%rip), %eax
我的问题是,100000f90
虚拟内存字节的实际地址还是偏移量?
链接器如何在执行之前给出实际地址?如果执行时该内存地址不可用怎么办?如果我在另一台内存少得多的机器上执行它会怎样(可能在这里开始分页)。
分配实际地址不是装载机的工作吗?
链接器是否为他的最终可执行文件生成实际地址?
解决方案
(以下答案假设链接器没有创建与位置无关的可执行文件。)
我的问题是,100000f90 是虚拟内存字节的实际地址还是偏移量?
这是实际的虚拟地址。严格来说,它是与代码段基址的偏移量,但由于现代操作系统总是将代码段的基址设置为 0,因此它实际上是实际的虚拟地址。
链接器如何在执行之前给出实际地址?如果执行时该内存地址不可用怎么办?如果我在另一台内存少得多的机器上执行它会怎样(可能在这里开始分页)。
每个进程都有自己独立的虚拟地址空间。因为它是虚拟内存,所以机器中的物理内存量无关紧要。分页是虚拟地址映射到物理地址的过程。
分配实际地址不是装载机的工作吗?
是的,在创建进程时,操作系统加载程序会为进程分配物理页框,并将页面映射到进程的虚拟地址空间。但是虚拟地址是由链接器分配的。
推荐阅读
- java - 验证、方法执行和JIT编译过程中类加载的原因和跟踪
- android - 未找到 Android Studio 中的各种属性
- android - 未指定 Android SDK 路径:SDK 路径位于空文件夹
- imagemagick - Magick.net 调整 GIF 大小,最终文件更大
- vba - 用户表单关闭时拉取选项按钮值
- keras - 训练和预测时的 Keras 功能智能中心
- c++ - 当我从 cin 读取时,为什么转义字符不起作用?
- php - 动态改变一个div的CSS属性类php
- javascript - React Native - 更新“affectedRows:0”并且删除未定义
- javascript - 网站中的实时流媒体在线编辑器