Предположим, что простой привет мир в 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
фактическим адресом байта виртуальной памяти или это смещение?
Как компоновщик может дать фактический адрес до выполнения? Что если этот адрес памяти недоступен при выполнении? Что делать, если я выполню его на другом компьютере с гораздо меньшим объемом памяти (возможно, здесь пейджинговые пинки).
Разве загрузчик не назначает фактические адреса?
Генерирует ли компоновщик фактические адреса для окончательного исполняемого файла?