Структура и образ памяти программы.СОМ
Рассмотрим пример законченной программы типа.СОМ, которая выводит на экран строку текста.
Пример 3.2. Простая.COM- программа.
assume CS:code,DS:code code segment org 256; Место под PSP main proc mov AH, 09h; Функция вывода на экран mov DX,offset msg int 21h mov AX,4C00h; Функция завершения int 21h; программы main endp msg db 16.16.16; Программа типа.COM'17.17.17,'$' code ends end main
В начале программы отведено 256 байт под PSP; в программе отсутствует инициализация регистра DS; поле данных размещено в программном сегменте непосредственно после последней команды. Для разнообразия в строку, выводимую на экран, включены коды 16 и 17, которые отображаются на экране в виде залитых треугольников (рис. 3.2). Как видно из этого рисунка, программа имела имя Р.СОМ и запускалась из каталога F:\CURRENT.
Рассмотрим важный в принципиальном плане вопрос о месте размещения данных в.СОМ-программе. В нашем примере данные описаны в конце программного сегмента вслед за процедурой main, которая, как и в предыдущих примерах, введена скорее для порядка, чем по необходимости.
Рис. 3.2. Вывод программы 3.2.
С таким же успехом можно было предложение с именем msg поместить после вызова int21h, внутри процедуры main. Третий возможный вариант, с которым мы еще столкнемся в примерах резидентных программ, приведен ниже.
assume CS:code,DS:code code segment org 256; Место под PSP main proc jmp start; Первая выполнимая команда msg db 16.16.16,; Программа типа.COM',17.17.17,'$' start: mov AH,09h; Функция вывода на экран mov DX,offset msg int 21h …; Продолжение программы
Таким образом, данные могут быть размещены как после программы, так и среди выполнимых предложений программы. Важно только соблюсти обязательное условие: ни при каких обстоятельствах на данные не должно быть передано управление. В первом случае (пример 3.2) данные помещены за вызовом функции DOS, завершающей программу. Ясно, что после выполнения этой функции управление уже не вернется в нашу программу, а будет передано командному процессору, поэтому размещение здесь данных вполне возможно. В последнем фрагменте данные описаны, можно сказать, в середине программы. Однако перед ними стоит команда безусловного перехода jmp, которая приводит при выполнении программы к обходу данных.
А вот чего нельзя было сделать, так это разместить данные после закрытия сегмента, как это сделано в приведенном ниже (неправильном!) фрагменте:
… main endp; Конец процедуры code ends; Конец сегмента msg db 16.16.16; Программа типа.COM',17.17.17,'$' end main
Это второе обязательное условие: из чего бы ни состояла программа, все ее компоненты должны входить в те или иные сегменты. Вне сегментов допускаются только нетранслируемые директивы ассемблера типа 0.586 или assume.
Наконец, третье условие, о котором уже говорилось, относится только к программам типа .COM.
DOS, загрузив программу в память, инициализирует указатель команд числом 100h, т.е. адресом первой команды вслед за оператором org 100h. Поэтому главная процедура. СОМ-программы (если в ней имеется несколько процедур) обязательно должна быть первой, причем первое предложение этой процедуры должно быть выполнимой командой (например, командой jmp, как это показано выше).