Почему адрес точки входа в моем исполняемом файле равен 0x8048330 (0x330 является смещением раздела .text) - программирование

Почему адрес точки входа в моем исполняемом файле равен 0x8048330 (0x330 является смещением раздела .text)

Я написал небольшую программу для добавления в целые числа и при использовании "readelf -a executable_name" он показал адрес точки входа в заголовке elf как:

Entry point address: 0x8048330

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

Также дайте мне знать, откуда исполняемый файл получает значение 0x8048330 в качестве адреса точки входа. просто для кросс-проверки я скомпилировал другую программу, и для этого также адрес точки входа остается тем же значением 0x8048330 (смещение секции .text в 0x330 в обоих случаях).

4b9b3361

Ответ 1

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

Чтобы использовать конкретный пример, рассмотрите следующее:

% file a.out
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, \
    for GNU/Linux 2.6.15, not stripped
% readelf -e a.out
... snip ...
Elf file type is EXEC (Executable file)
Entry point 0x8048170
There are 6 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x08048000 0x08048000 0x7cca6 0x7cca6 R E 0x1000
  LOAD           0x07cf98 0x080c5f98 0x080c5f98 0x00788 0x022fc RW  0x1000
... snip ...

Первый заголовок программы указывает, что содержимое файла в смещение файла 0 должно быть сопоставлено с виртуальным адресом 0x08048000. размер файла и памяти для этого сегмента - 0x7cca6 байт. Эта сегмент должен отображаться в читаемом и исполняемом файле, но не доступен для записи (он содержит программный код).

Адрес точки входа, указанный в заголовке ELF, равен 0x8048170, что попадает в область, содержащую программный код.

Книга "Линкеры и погрузчики" Джона Левина - хороший ресурс для консультаций по вопросам, связанным с редакторами ссылок и загрузчиками.

Ответ 2

Для первого вопроса:

Точка входа, которую вы видели, 0x8048330, является адресом виртуальной памяти (которая в обратном случае является физической памятью), что означает, что ваш руководитель не должен знать, какой физический адрес после загрузки. к процессу вашей программы, ваш .text всегда начинается с 0x8048330, ваша система (ОС и аппаратное обеспечение) будет отображать ее в физической памяти во время выполнения.

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

Для второго вопроса

Я не уверен, какая часть вас путала, поэтому я попытаюсь их охватить:

  • Может ли более чем одна программа иметь такую ​​же точку входа?

Да, может быть другая программа имеет ту же точку входа 0x8048330. поскольку этот адрес является виртуальным, программы будут отображаться в другую физическую память, когда вы запускаете их в одно и то же время.

  • Всегда ли запись 0x8048330?

Ну, руководители Linux начинаются с 0x8048000, но смещение .text связано с длиной других разделов. так что нет, это может быть 0x8048034 или что-то еще.

  • Почему он всегда начинается с 0x8048000?

Я думаю, что это какая-то история, дизайнер Linux выбрал эту для какой-то неизвестной или даже случайной причины. вы можете сослаться на этот поток, чтобы узнать, что в этой области.

Ответ 3

О вопросе виртуального адреса:

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

Таким образом, ОС не позволяет приложениям считывать/записывать в другую память приложений или зарезервированную память ОС. Кроме того, это позволяет пейджинг памяти (использовать жесткий диск как память) прозрачным способом для приложения.