Для СОМ-файла DOS автоматически определяет стек и устанавливает одинаковый общий сегментный адрес во всех четырех сегментных регистрах. Если для программы размер сегмента в 64 К достаточен, то DOS устанавливает в регистре SP адрес конца сегмента - FFFE. Это будет вершина стека. Если 64-Кбайтный сегмент не имеет достаточно места для стека, то DOS устанавливает стек в конце памяти. В обоих случаях DOS записывает затем в стек нулевое слово.
Возможность использования стека зависит от размера программы и ограниченности памяти. С помощью команды DIR можно определить размер файла и вычислить необходимое пространство для стека.
Особенность отладки
Несоблюдение хотя бы одного требования СОМ-формата может послужить причиной неправильной работы программы. Необходимо правильно писать в этом случае - директивы SEGMENT, ASSUME и END. Если опущена директива ORG 100H, то на данные в префиксе программного сегмента будут установлены неправильные ссылки с непредсказуемым результатом при выполнении.
Попытка выполнить ЕХЕ-модуль программы, написанной для СОМ-формата, успеха не имеет.
Пример программы типа ЕХЕ
ЕХЕ-программы немного сложнее в исполнении, но для них отсутствует ограничение размера в 64 килобайта, так что все достаточно большие программы используют именно этот формат. Конечно, ассемблер позволяет уместить и в 64 килобайтах весьма сложные и большие алгоритмы, а все данные хранить в отдельных файлах, но ограничение размера все равно очень серьезно, и даже чисто ассемблерные программы могут с ним сталкиваться.
; hello-2.asm; Выводит на экран сообщение " Hello World " и завершается .model small ; модель памяти, используемая для ЕХЕ .stack 100h ; сегмент стека размером в 256 байт .codestart: mov ax,@data ; сегментный адрес строки message; mov ax,DGROUP ; группы сегментов данных DGROUP mov ds,ax ; помещается в DS mov dx,offset message mov ah,9 int 21h ; функция DOS "вывод строки" mov ax,4C00h int 21h ; функция DOS "завершить программу" .data@data message db "Hello World!",0Dh,0Ah,'$' end start
Рис. 6.17.Пример программы типа ЕХЕ
В этом примере определяются три сегмента — сегмент стека директивой .STACK размером в 256 байт, сегмент кода, начинающийся с директивы .CODE, и сегмент данных, начинающийся с .DATA и содержащий строку. При запуске ЕХE-программы регистр DS уже не содержит адреса сегмента со строкой message (он указывает на сегмент, содержащий блок данных PSP), а для вызова используемой функции DOS этот регистр должен иметь сегментный адрес строки. Команда MOV AX,DGROUP загружает в АХ сегментный адрес группы сегментов данных DGROUP, a MOV DS,AX копирует его в DS. Для ассемблеров MASM и TASM можно использовать вместо DGROUP предопределенную метку «@data», но единственная модель памяти, в которой группа сегментов данных называется иначе, — FLAT (ей мы пока пользоваться не будем). И наконец, программы типа ЕХЕ должны завершаться системным вызовом DOS 4Ch: в регистр АН помещается значение 4Ch, в регистр AL помещается код возврата (в данном примере код возврата 0 и регистры АН и AL загружаются одной командой MOV AX,4C00h), после чего вызывается прерывание 21h.
Список литературы по разделу «Ассемблер»
1. К. Хамахер и др. Организация ЭВМ, Питер, 2003-2005
2. Бауэр Ф.Л. Информатика, изд. Мир, М. 2001
3. Зубков С.В. Ассемблер. Язык неограниченных возможностей, ДМК Пресс, 1999
4. Абель М. Язык ассемблера для IBM PC и программирования. Высшая школа. М.
5. Любой учебник по ассемблеру персонального компьютера и процессора Intel.