Файл, который вводится в качестве вставки в компоновщик, называется Файл объекта. Компилятор создает файл изображения, который, в свою очередь, используется в качестве входа загрузчика.
Сводка из " Спецификация формата файлов Microsoft Executable и Common Object
RVA (относительный виртуальный адрес). В файле изображения адрес элемента после его загрузки в память, с базовый адрес файла изображения вычитается из него. RVA элемента почти всегда отличается от положение в файле на диске (файл указатель).
В объектном файле RVA меньше значимым, поскольку ячейки памяти не назначены. В этом случае RVA будет адресом в секции (описанный далее в этой таблице), чтобы которые позднее применяются к перемещению во время связывания. Для простоты компилятор должен просто установить первый RVA в каждом разделе до нуля.
VA (виртуальный адрес). То же, что и RVA, за исключением того, что базовый адрес файл изображения не вычитается. адрес называется "VA", потому что Windows создает отдельное пространство VA для каждого процесса, независимо от физическая память. Почти для всех целей, ВА следует рассматривать просто адрес. VA не так предсказуемым как RVA, поскольку загрузчик может не загружать изображение на своем предпочтительное местоположение.
Даже после прочтения этого я все равно не понимаю. У меня много вопросов. Может ли кто-нибудь объяснить это практическим способом. Пожалуйста, придерживайтесь терминологии Object File
и Image File
, как указано.
Все, что я знаю об адресах, заключается в том, что
- Ни в объектном файле, ни в файле изображений мы не знаем точных мест памяти, поэтому
- Ассемблер при создании Object File вычисляет адреса по разделам
.data
и.text
(для имен функций). - Линкером, принимающим несколько объектных файлов в качестве входных данных, генерируется один файл изображения. Во время генерации он сначала объединяет все разделы каждого объектного файла, и при слиянии он повторно пересчитывает смещения адреса по отношению к каждому разделу. И нет ничего подобного глобальным смещениям.
Если что-то не так в том, что я знаю, пожалуйста, поправьте меня.
EDIT:
После прочтения ответа, данного Фрэнсисом, я понимаю, что такое Физический адрес, VA и RVA и какова связь между ними.
RVAs всех переменных & методы должны быть вычислены Linker во время перемещения. Итак, (значение RVA метода/переменной) == (его смещение от начала файла)? должно быть правдой. Но удивительно, его нет. Почему так?
Я проверил это, используя PEView на c:\WINDOWS\system32\kernel32.dll
и обнаружил, что:
- RVA и FileOffset одинаковы до начала разделов. (
.text
- это первый раздел в этой DLL). - В начале
.text
через.data
,.rsrc
до последнего байта последнего раздела (.reloc
) значения RVA и FileOffset различны. а также RVA первого байта первой секции "всегда" отображается как0x1000
- Интересно, что байты каждого раздела непрерывны в FileOffset. Я имею в виду, что другой раздел начинается с следующего байта последнего байта раздела. Но если я вижу то же самое в RVA, это огромный разрыв между RVAs последнего байта раздела и первого байта следующего раздела.
Мой угадай:
-
Все, байты данных, которые были перед первым (
.text
здесь) раздел "не" фактически загружен в VA-пространстве процесса, эти байты данных используются только для найти и описать эти разделы. Их можно назвать "мета-секцией" данных ".Поскольку они не загружаются в VA пространства процесса. использование термин RVA также бессмысленен, это причина, по которой
RVA == FileOffset
для этих байтов. -
Так как,
- Термин RVA действителен только для тех байтов, которые будут фактически загружены в пространство VA.
- байты
.text
,.data
,.rsrc
,.reloc
являются такими байтами. - Вместо запуска с RVA
0x00000
запускается программное обеспечение PEView это от0x1000
.
-
Я не могу понять, почему произошло третье наблюдение. Я не могу объяснить.