Генерирует ли компоновщик абсолютные виртуальные адреса при компоновке - PullRequest
1 голос
/ 16 марта 2019

Предположим, что простой привет мир в 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 фактическим адресом байта виртуальной памяти или это смещение?

Как компоновщик может дать фактический адрес до выполнения? Что если этот адрес памяти недоступен при выполнении? Что делать, если я выполню его на другом компьютере с гораздо меньшим объемом памяти (возможно, здесь пейджинговые пинки).

Разве загрузчик не назначает фактические адреса?

Генерирует ли компоновщик фактические адреса для окончательного исполняемого файла?

Ответы [ 2 ]

1 голос
/ 17 марта 2019

(Следующие ответы предполагают, что компоновщик не создает независимый от позиции исполняемый файл.)

У меня вопрос, является ли 100000f90 фактическим адресом байта виртуальной памяти или это смещение?

Это фактический виртуальный адрес. Строго говоря, это смещение от базы сегмента кода, но поскольку современные операционные системы всегда устанавливают базу сегмента кода на 0, это фактически фактический виртуальный адрес.

Как компоновщик может дать фактический адрес до выполнения? Что если этот адрес памяти недоступен при выполнении? Что делать, если я выполню его на другом компьютере с гораздо меньшим объемом памяти (возможно, здесь пейджинговые пинки).

Каждый процесс получает свое собственное отдельное виртуальное адресное пространство. Поскольку это виртуальная память, объем физической памяти в машине не имеет значения. Пейджинг - это процесс, с помощью которого виртуальные адреса отображаются на физический адрес.

Разве загрузчик не назначает фактические адреса?

Да, при создании процесса загрузчик операционной системы выделяет физические фреймы страниц для процесса и отображает страницы в виртуальное адресное пространство процесса. Но виртуальные адреса назначаются компоновщиком.

0 голосов
/ 18 марта 2019

Генерирует ли компоновщик абсолютные виртуальные адреса при компоновке

Это зависит от настроек компоновщика и источника входного сигнала.Для общего программирования линкеры обычно стремятся создать независимый от позиции код.

Мой вопрос: 100000f90 - это фактический адрес байта виртуальной памяти или это смещение?

Скорее всего, это смещение.

Как компоновщик может дать фактический адрес до выполнения?

Подумайте о загрузчике для операционной системы.Он ожидает, что вещи будут в определенных адресных местах.Любой приличный компоновщик позволит программисту каким-то образом указывать абсолютные адреса.

Что если этот адрес памяти не доступен при выполнении?Что делать, если я выполню его на другом компьютере с гораздо меньшим объемом памяти (возможно, здесь пейджинговые пики).

Это проблема с позиционно-зависимым кодом.

Не являетсяэто работа загрузчика, чтобы назначить фактические адреса?

Работа загрузчика состоит в том, чтобы следовать инструкциям, данным ему в исполняемом файле.При создании исполняемого файла в некоторых случаях компоновщик может указать адреса или отложить загрузчик.

...