У всі
скомпільовані й скомпоновані завантажувальні модулі включається спеціальний
модуль COx.OBJ. Він включає дві основні секції: завантажник, або стартер (Startup Code);
функції завершення (Exit Code). Структура і алгоритм
роботи завантажника залежать від обраної
моделі пам’яті, в склад Turbo С включені варіанти для
кожної з них. головна задача цієї програми - сформувати завантажувальний модуль
точно в відповідності з представленнями програміста про його структуру,
передати керування функції main (), а після її
завершення виконати заключну секцію.
Програма-завантажник, одержавши
керування, виконує наступні дії:
1) зберігає в кодовому сегменті сегмент адреса, з якого починається секція
даних DGROUP;
2) ініціалізує в сегменті даних ряд зовнішніх
змінних: номер версії MS-DOS, сегмент адреса початку PSP програми, сегмент
адреса середовища програми, сегмент адреса границі оперативної пам’яті і ін.;
3) зберігає в сегменті даних
деякі вектори переривання (вектори 0, 4, 5, 6 і ін.) та установлює власний
оброблювач переривання 0. установлений оброблювач буде друкувати повідомлення 'Divide error' та аварійно
завершувати програму при виникненні виняткової ситуації ділення на нуль;
4) формує середовище програми
(вид отриманого середовища див. в 5.1) і аргументи, передані в точку входу main (); ці аргументи доступні програмі, якщо точка входу
описується як main(int argc, char **argv,
char **env);
5) звільняє не використовувану програмою оперативну пам’ять;
6) виконує настроювання програми на апаратуру, якщо в програмі мається код
для математики з плаваючою крапкою і
компіляція виконується з опцією Emulation (див. першу
книгу комплексу);
7) налагоджує регістри процесора у відповідності з моделлю пам’яті (див.
далі);
8) викликає процедуру main();
Після завершення
виконання main() керування знову одержує модуль COx.OBJ, який виконує дії по завершенню програми:
9) відновлює вектори переривання
0, 4,5, б та ін.;
10) закриває файли, відкриті у
ході виконання програми;
11) виконує одну з
функцій MS-DOS завершення програм.
Розміри завантажника
достатньо великі; це особливо помітно для невеликих програм. завдяки роботі
програми-завантажника, оперативна пам’ять перед входом в main
() знаходиться в стані, зображеному на Рис. 6.2.
Програма розташовується в
двох блоках пам’яті: перший займає
середовище програми, а другий - завантажувальний модуль. Перед передачею
керування в main () оперативна пам’ять, не
використовувана програмою, вже звільнена завантажником. У наслідку ця пам’ять
використовується під far-«кучу».
|
0 |
+1 |
+3 +Fh |
|||
Блок середовища (L_ENVпараграфів) Блок завантажувального модуля (L_PRJ параграфів) Вільний
блок (L_END параграфів) |
‘M’ |
S_PSP |
L_ENV ... |
|||
SEG:0000 |
ASCIIZ-рядки
середовища, специфікація файлу завантажувального модуля програми |
|||||
|
‘M’ |
S_PSP |
L_PRJ ... |
|||
S_PSP:0000 |
CD 20... (INT 20h) |
|||||
|
+Ch +Eh +Fh |
|||||
S_PSP:0020 |
|
SEG |
|
|||
|
|
|||||
S_PSP+10:0000 |
Завантажувальний модуль
(структура залежить від моделі пам'яті) |
|||||
MCB |
‘Z’ |
00 00 |
L_END |
|||
|
Вільний |
|||||
Рис. 6.2. Стан пам’яті
перед запуском функції main ()
![]() |
![]() |
![]() |