虚拟地址何时分配给程序/进程?Linux下C程序编译加载相关疑问
Great question—even foundational topics like this deserve clear breakdowns to avoid gaps in understanding. Let's walk through this step by step:
What kind of addresses are in the a.out file?
Yes, the addresses stored in your compiled/linked a.out (an ELF-format executable on Linux) are virtual addresses—though the exact type depends on whether you built a Position-Independent Executable (PIE) or a traditional fixed-address executable:
- On modern Ubuntu releases, GCC compiles to PIE by default. Here, the addresses in
a.outare offsets relative to a base virtual address that the kernel will select randomly when loading the program (thanks to ASLR, Address Space Layout Randomization). - If you compile with the
-no-pieflag, you'll get a non-PIE executable. In this case, the addresses are fixed virtual addresses (for example, the.textcode segment typically starts at0x400000).
In both cases, these are addresses meant for the virtual memory space of a process, not physical memory addresses.
When do virtual addresses start playing a role?
Virtual addresses enter the picture as early as the linking phase:
- Compilation: The compiler outputs object files with symbolic references (not concrete addresses) and offsets within each section (like
.textor.data). - Linking: The linker resolves all symbolic references and assigns each segment to a specific location in the virtual address space. This is when the virtual addresses (or PIE offsets) get written into the final
a.outfile. - Loading: When you run the executable, the kernel's loader maps the ELF segments to the virtual address space of the new process. For PIEs, it picks a random base address and adjusts the offsets from
a.outto fit this base. For non-PIEs, it maps segments directly to the fixed virtual addresses specified in the executable. - Execution: Once loaded, the CPU uses the virtual addresses from the executable. The Memory Management Unit (MMU) in the CPU translates these virtual addresses to physical memory addresses on the fly—this is how virtual memory provides process isolation, efficient memory sharing, and protection.
To sum up: The linker starts assigning virtual addresses during the build process, and the kernel makes them operational when loading the process into memory.
内容的提问来源于stack exchange,提问作者Usr1

