Сборщик tlink.exe формирует из объектных модулей файл, готовый для выполнения. Этот файл называется загрузочным модулем. Он может быть построен двумя способами. В зависимости от способа построения он имеет расширение EXE или COM.
Размещение программы в памяти. Для выполнения программы пользователя операционная система (точнее загрузчик COMMAND.COM) размещает коды программы в свободной оперативной памяти и добавляет перед программой состоящий из 256 байт блок, который называется префиксом программного сегмента (PSP). После размещения операционная система передаёт управление в точку входа этой программы (определенную как операнд директивы end). Операционная система при этом производит следующие действия:
1) определяет сегментный адрес префикса программного сегмента (PSP);
2) создает два блока памяти – блок памяти для переменных среды и блок памяти для PSP и программы;
3) в блок памяти переменных среды помещает путь, откуда была загружена программа;
4) заполняет поля PSP.
Загрузочный модуль размещается в памяти следующим образом:
Сначала идет PSP (256 байт). Затем коды программы. Затем — данные программы, после которых идут неинициализируемые данные. Стек размещается в конце сегмента стека (который в случае COM совпадает с сегментом кодов).
Регистры DS и ES после размещения программы пользователя указывают на PSP.
Загрузочный модуль, как файл, может существовать в одном из двух форматов: EXE и COM. Формат EXE отличается от COM тем, что он содержит специальный начальный блок, который называется заголовком и занимает не менее 512 байт.
При загрузке программы DS и ES указывают на PSP и запоминаются поля PSP, но дальнейшие действия зависят от формата файла.
Файл EXE загружается, начиная с адреса PSP:100h. В момент загрузки файла EXE регистры CS, IP, SS и SP инициализируются значениями, указанными в заголовке.
Регистры DS и ES указывают на PSP. CS устанавливается на начало сегмента кодов.
Файл COM состоит из единственного сегмента. Образ файла COM помещается, начиная с адреса PSP:100h. Регистры CS и SS указывают на PSP, регистр SP – на конец сегмента PSP (т.е. SP=0FFFEh), регистр IP равен 100h.
В первых байтах PSP записывается команда int 20h (выход в операционную систему). Стало быть, если выполнить в начале программы EXE команды
push es
mov ax,0
push ax
то, в случае, если встретится команда ret, произойдет переход по адресу ES:0 на команду int 20h. Если же вместо ret использовать для возврата в операционную систему к
оманду int 20h непосредственно в программе, то, поскольку сегмент вызывающей программы будет отличаться от PSP, адрес возврата будет вычисляться некорректно.
В программе COM эти шаги инициализации регистра DS и записи нулевого слова в стек не нужны. Эти действия производит загрузчик. Выход можно осуществлять с помощью команды RET. Так как адресация начинается со смещения 100h от начала PSP, то программа COM должна содержать директиву ORG 100h (после оператора SEGMENT).
Основное отличие формата COM от EXE заключается в том, что размер программы COM не больше 64 Кбайт и все данные, коды команд и область стека в ней размещаются в одном сегменте.
Пример. Рассмотрим программу, которая все символы строки превращает в соответствующие этим символам большие буквы
<1> TITLE UEX.COM
<2> codesg segment
<3> assume cs:codesg, ds:codesg, ss:codesg
<4> org 100h
<5> begin: jmp main
<6> text db ‘abcdefghijABCDEFGHIJ0123456789 $’
<7> main proc near
<8> lea bx,text
<9> mov cx,31 ;число символов
<10> b20: mov ah,[bx] ;если символ
<11> cmp ah,’a’ ;не принадлежит диапазону
<12> jb b30 ;от ‘a’ до ‘z’
<13> cmp ah,’z’ ;то переходим к
<14> ja b30 ;следующему символу
<15> and ah,11011111b;очищаем бит 5
<16> mov [bx],ah ;записываем новый символ
<17> b30: inc bx ;bx указывает на
<18> loop b20 ;следующий символ
<19> lea dx,text
<20> mov al,0
<21> mov ah,9 ;вывод строки
<22> int 21h ;на экран
<23> ret
<24> main endp
<25> codesg ends
<26> end begin