МИНОБРНАУКИ РОССИИ
Санкт-Петербургский государственный
электротехнический университет
«ЛЭТИ» им. В.И. Ульянова (Ленина)
Кафедра математического обеспечения и применения ЭВМ
отчет
По лабораторной работе № 1
по дисциплине «Операционные системы»
Тема Исследование структур загрузочных модулей
Студент гр. 0303 |
|
Болкунов В.О. |
Преподаватель |
|
Губкин А. Ф. |
2022
Цель работы.
Исследование различий в структурах исходных текстов модулей типов .СОМ и .ЕХЕ, структур файлов загрузочных модулей и способов их загрузки в основную память.
Порядок выполнения работы.
«Истина познается в сравнении», как говорили древние. К счастью, у нас есть возможность исследовать в одной системе два различных формата загрузочных модулей, сравнить их и лучше понять как система программирования и управляющая программа обращаются с ними. Система программирования включает компилятор с языка ассемблер (часто называется, просто, ассемблер), который изготавливает объектные модули. Компоновщик (Linker) по совокупности объектных модулей, изготавливает загрузочный модуль, а также, функция ядра – загрузчик, которая помещает программу в основную память и запускает на выполнение. Все эти компоненты согласованно работают для изготовления и выполнения загрузочных модулей разного типа. Для выполнения лабораторной работы сначала нужно изготовить загрузочные модули.
Шаг 1. Напишите текст исходного .СОМ модуля, который определяет тип РС и версию системы. Это довольно простая задача и для тех, кто уже имеет опыт программирования на ассемблере, это будет небольшой разминкой. Для тех, кто раньше не сталкивался с программированием на ассемблере, это неплохая задача для первого опыта. За основу возьмите шаблон, приведенный в разделе «Основные сведения». Необходимые сведения о том, как извлечь требуемую информацию, представлены в следующем разделе. Ассемблерная программа должна читать содержимое предпоследнего байта ROM BIOS, по таблице, сравнивая коды, определять тип РС и выводить строку с названием модели. Если код не совпадает ни с одним значением, то двоичный код переводиться в символьную строку, содержащую запись шестнадцатеричного числа и выводиться на экран в виде соответствующего сообщения. Затем определяется версия системы. Ассемблерная программа должна по значениям регистров AL и AH формировать текстовую строку в формате xx.yy, где xx - номер основной версии, а yy - номер модификации в десятичной системе счисления, формировать строки с серийным номером OEM и серийным номером пользователя. Полученные строки выводятся на экран. Отладьте полученный исходный модуль. Результатом выполнения этого шага будет «хороший» .СОМ модуль, а также необходимо построить «плохой» .ЕХЕ, полученный из исходного текста для .СОМ модуля.
Шаг 2. Напишите текст исходного .ЕХЕ модуля, который выполняет те же функции, что и модуль в Шаге 1 и постройте и отладьте его. Таким образом, будет получен «хороший» .ЕХЕ.
Шаг 3. Сравните исходные тексты для .СОМ и .ЕХЕ модулей. Ответьте на контрольные вопросы «Отличия исходных текстов СОМ и ЕХЕ программ».
Шаг 4. Запустите FAR и откройте (F3/F4) файл загрузочного модуля .СОМ и файл «плохого» .ЕХЕ в шестнадцатеричном виде. Затем откройте (F3/F4) файл загрузочного модуля «хорошего» .ЕХЕ и сравните его с предыдущими файлами. Ответьте на контрольные вопросы «Отличия форматов файлов СОМ и ЕХЕ модулей».
Шаг 5. Откройте отладчик TD.EXE и загрузите .СОМ. Ответьте на контрольные вопросы «Загрузка СОМ модуля в основную память». Представьте в отчете план загрузки модуля .СОМ в основную память.
Шаг 6. Откройте отладчик TD.EXE и загрузите «хороший» .ЕХЕ. Ответьте на контрольные вопросы «Загрузка «хорошего» ЕХЕ модуля в основную память».
Шаг 7. Оформление отчета в соответствии с требованиями. В отчете необходимо привести скриншоты. Для файлов их вид в шестнадцатеричном виде, для загрузочных модулей – в отладчике.
Выполнение работы.
Данные:
endLine - символы для перевода строки
version - строчка версии
verNumOffset - смещение номера версии
modNumOffset - смещение модификации версии
oem - строка с OEM кодом
oemNumOffset - смещение числа кода
serial - строка серийного номера
serialNumOffset - смещение числа серийного номера
typePcStr - строка с типом ПК
typePC - строки с различными типами ПК
typePCXT
typeAT
typePS2M30
typePS2M5060
typePS2M80
typePCJR
typePCCONV
typeOther
typeOtherOffset
Макроопределения и процедуры:
print _str_ - вывод строки на экран
PCTypePrint - вывод типа ПК
OSVersionPrint - вывод версии DOS
TETR_TO_HEX - процедуры для перевода чисел из шаблона
BYTE_TO_HEX
WRD_TO_HEX
BYTE_TO_DEC
Загрузочные модули собираются из файлов com_prog.asm и exe_prog.asm, с помощью утилит “masm”, “link” и “exe2bin”, для автоматизации сборки написаны скрипты build_com.bat и build_exe.bat. Пример работы .com и .exe модулей показан на рисунках 1 и 2 соответственно. На рисунке 3 представлен результат работы «плохого» exe модуля, который получился при компиляции исходного текста программы, предназначенной для сборки в com модуль.
Рисунок 1: «хороший» com модуль
Рисунок 2: "хороший" exe модуль
Рисунок 3: "плохой" exe модуль
На следующих скриншотах представлены собранные загрузочные модули в 16ричном виде.
Рисунок 4: com модуль
Рисунок 5: "плохой" exe модуль
Рисунок 6: "хороший" exe модуль
На следующих скриншотах представлены загруженные в ОП загрузочные модули, запущенные в отладчике (TurboDebugger)
Рисунок 7: com модуль в дебаггере
Рисунок 8: exe модуль в дебаггере
Контрольные вопросы
Отличия исходных текстов СОМ и ЕХЕ программ
Сколько сегментов должна содержать COM-программа?
- один сегмент (в котором находятся данные, код и стек вместе)
EXE-программа?
- один и более сегментов (обычно код, данные и стек имеют собственные сегменты)
Какие директивы должны обязательно быть в тексте COM-программы?
<имя> segment
- указание сегмента (так как COM модуль занимает ровно 1 сегмент)
org 100h
- указание для смещения программы при запуске на 256 байт. Так как при загрузке COM модуля в ОП, необходимо зарезервировать 256 байт под префикс программного сегмента (PSP).
assume cs: <сегмент>, ds: <сегмент>
- чтобы сообщить ассемблеру адрес какого сегмента должен находится в сегментных регистрах
Все ли форматы команд можно использовать в COM-программе?
- нельзя использовать команду seg <операнд>, однако отсутствует необходимость её использовать, так как весь модуль и так находится в одном сегменте.
Какова структура файла COM? С какого адреса располагается код?
- код и данные в одном сегменте (а стек создаётся автоматически с конца сегмента). Код располагается с адреса 0h.
2) Какова структура файла «плохого» EXE? С какого адреса располагается код? Что располагается с адреса 0?
- в «плохом» EXE данные и код содержатся в одном сегменте.
С адреса 0h идёт таблица настроек (Relocation table). Код располагается с адреса 300h.
Какова структура файла «хорошего» EXE? Чем он отличается от файла
«плохого» EXE?
- в «хорошем» .exe файле код, данные и стек находятся в разных сегментах. Также в «плохом» .exe адресация кода начинается с 300h, так как он получается из .com файла, в котором изначально сегмент кода смещён на 100h, а при создании «плохого» .exe к этому смещению добавляется размер PSP равный 200h. А в «хорошем» .exe присутствует только смещение для PSP, поэтому код начинается с 200h.
1) Какой формат загрузки модуля COM? С какого адреса располагается код?
- .com файл помещается в память, начиная с адреса (внутри сегмента) 0100h. После загрузки .com программы сегментные регистры CS, DS, ES и SS указывают на адрес сегмента программы (в данном случае 543Bh), SP указывает на конец сегмента программы, там находится вершина стека (который растёт вниз – по убыванию адреса). Регистр IP содержит 100H (фактическое начало программы)
2) Что располагается с адреса 0?
- Program Segment Prefix (PSP) размером в 100h байт
3) Какие значения имеют сегментные регистры? На какие области памяти они указывают?
- При загрузке программы они указывают на начало сегмента программы.
Как определяется стек? Какую область памяти он занимает? Какие адреса?
- стек автоматически помещается в конец сегмента и растёт по
убыванию адреса (смещения) относительно сегмента.
Как загружается «хороший» EXE? Какие значения имеют сегментные регистры?
- регистры CS и SS (отвечающие за сегмент кода и стека), в данном
случае они имеют значения 543Bh и 546Fh соответственно и инициализированы сразу (после загрузки программы), а регистр сегмента данных DS устанавливается уже во время исполнения с помощью последовательности команд :
mov ax, @data
mov ds, ax
Регистр SP содержит указатель на вершину стека 100h (именно такого размера сегмент стека был указан в программе)
На что указывают регистры DS и ES?
- DS и ES – регистр сегмента данных и дополнительный сегментный регистр соответственно, по умолчанию (при загрузки программы) они указывают на сегмент программы (начало PSP).
3) Как определяется стек?
- стек имеет собственный сегмент (указан в регистре SS), его размер указывается командой .stack
4) Как определяется точка входа?
- директива end <имя> определяет точку входа в программу (метка с именем точки должна быть объявлена выше)
В ходе лабораторной работы были исследованы структуры организации загрузочных .com и .exe модулей, написаны исходные коды программ (собранных в эти два типа модулей) выводящих информацию о типе компьютера и версии ОС (для DOS). Также было исследована загрузка этих типов загрузочных модулей в оперативную память с помощью отладчика.