- •1. Основы программирования для dos 9
- •1.1.7. Средства bios 21
- •2. Приемы системного программирования 57
- •Введение
- •1.Основы программирования для dos
- •1.1. Структура и выполнение программ в dos
- •Программа типа сом
- •Программа типа ехе
- •1.2.Использование служебных функций dos и bios
- •1.3.Вывод на экран в текстовом режиме
- •Средства dos
- •Средства bios
- •Выбор видеорежима
- •Управление положением курсора
- •Вывод символов на экран
- •Прямая работа с видеопамятью
- •1.4.Ввод с клавиатуры
- •Средства dos
- •Средства bios
- •1.5.Графические видеорежимы
- •Работа со стандартными графическими режимами
- •Работа с svga-режимами
- •(Продолжение таблицы 4)
- •(Окончание таблицы 4)
- •1.6.Работа с мышью
- •1.7.Другие устройства
- •Системный таймер
- •Последовательный порт
- •Параллельный порт
- •1.8.Работа с файлами
- •Создание и открытие файлов
- •Чтение из файла и запись в файл
- •Закрытие и удаление файла
- •Поиск файлов
- •Управление файловой системой
- •1.9.Управление памятью
- •Обычная память
- •Область памяти umв
- •Область памяти нма
- •Интерфейс ems
- •Интерфейс xms
- •1.10.Организация процессов
- •Запуск программ на выполнение
- •Переменные окружения
- •Командные параметры
- •2.Приемы системного программирования
- •2.1.Управляющие структуры
- •Структуры if... Then... Else
- •Структуры case
- •Конечные автоматы
- •2.2.Процедуры и функции
- •Передача параметров
- •Передача параметров по значению
- •Передача параметров по ссылке
- •Передача параметров по возвращаемому значению
- •Передача параметров по результату
- •Передача параметров по имени
- •Передача параметров отложенным вычислением
- •Передача параметров в регистрах
- •Передача параметров в глобальных переменных
- •Передача параметров в стеке
- •Передача параметров в потоке кода
- •Передача параметров в блоке параметров
- •Локальные переменные
- •2.3.Обработка прерываний
- •Обработчики прерываний
- •Прерывания от внешних устройств
- •Взаимодействие прикладных и системных обработчиков прерываний
- •2.4.Резидентные программы
- •Системные средства организации резидентных программ
- •Взаимодействие с резидентной программой
- •2.5.Драйверы устройств в dos
- •Литература
Программа типа сом
Как уже говорилось, СОМ-программа не может занимать более одного сегмента памяти, т. е. 64 Кб. При запуске СОМ-файла командный процессор помещает содержимое программы в память практически без изменений и передает управление на первый байт программы. В связи с этим программа обязательно должна начинаться с команды, а не с данных. Кроме того, программист должен сам зарезервировать в программе место для системной области данных PSP; обычно это делается с помощью директивы управления программным счетчиком ORG (подробнее о размещении программы в памяти и о структуре PSP см. раздел 1.10).
Несмотря на то, что СОМ-программа не может занимать более одного сегмента памяти, в ней вполне могут присутствовать (и обычно присутствуют) и код, и данные, и стек. В этом случае можно говорить о наложении друг на друга нескольких сегментов.
Структура СОМ-программы в исходном тексте может быть описана с помощью модели памяти TINY:
.model tiny ; модель памяти, используемая для СОМ-программ
.code ; начало сегмента кода
org 256 ; начальное значение программного счетчика - 256
; участок кода
start: ; точка входа в программу
[. . .] ; (содержательная часть)
mov ah, 4Ch ; подготовка к вызову функции выхода
int 21h ; точка выхода
; участок данных
message db 1, 2, 3, 'data'
end start ; конец программы с указанием точки входа
В модели памяти TINY сегменты кода, данных и стека объединены в один сегмент (с именем _text). Начало сегмента описывается директивой .CODE. Конец сегмента совпадает с концом программы и указывается директивой END.
Другой вариант описания исходного текста СОМ-программы — с помощью директив сегментации SEGMENT-ENDS и директивы ASSUME, устанавливающей соответствие между сегментными регистрами и сегментами (в данном случае — единственным сегментом) программы:
text segment ; начало описания сегмента СОМ-программы
assume cs:text, ds:text ; регистры CS и DS связаны с сегментом text
org 256 ; начальное значение программного счетчика - 256
; участок кода
start: ; точка входа в программу
[. . .] ; (содержательная часть)
mov ah, 4Ch ; подготовка к вызову функции выхода
int 21h ; точка выхода
; участок данных
message db 1, 2, 3, 'data'
text ends ; конец описания сегмента
end start ; конец программы с указанием точки входа
Как видно, для указания конца описания сегмента здесь имеется специальная директива ENDS.
Директива ORG 256 предназначена для резервирования 256 байт для PSP, после чего указывается метка (в данном случае START:), с которой начнется выполнение программы (точка входа). Как уже говорилось, в СОМ-программах метка точки входа обязательно должна указывать на первую же после PSP команду.
Содержательная часть в приведенных выше примерах отсутствует, поэтому первой командой является подготовка к завершению работы. Завершение осуществляется при помощи функции DOS 4Ch прерывания 21h (большинство функций DOS вызываются с использованием прерывания 21h, поэтому часто о нем не упоминают; отличные же ситуации оговариваются отдельно). Последняя команда программы — INT 21h — вызывает указанную выше функцию, которая и возвращает управление командному процессору.
После описания кодовой части программы идет описание данных, выполненное в данном случае с помощью директивы DB резервирования байтовых ячеек памяти. Три первых байта определены в виде непосредственных десятичных чисел, а следующие 4 — в символьном виде. Ассемблер преобразует указанные символы в числа в соответствии со стандартной кодировкой символов ASCII. Относительный адрес описанных данных (то есть смещение данных относительно начала сегмента) представлен символьным именем MESSAGE.
Директива END в последней строке завершает программу, одновременно указывая, с какой метки должно начинаться выполнение программы.
Чтобы превратить исходную программу (предположим, записанную в файле name.asm) в исполнимый файл, сначала надо вызвать ассемблер, набрав в командной строке следующую команду:
В случае использования пакета TASM:
tasm name.asm
В случае использования пакета MASM:
ml /c name.asm
В результате программа скомпилируется ее в объектный файл с именем name.obj.
Следующий шаг — вызов компоновщика, преобразующего объектный файл в исполнимый. Рассматриваемые здесь ассемблеры по умолчанию используют единый формат объектных файлов (OMF-формат), так что можно пользоваться ассемблером из одного пакета и компоновщиком из другого.
При использовании компоновщика TLINK строка вызова имеет вид:
tlink /t /x name.obj
В системе MASM компоновка программы выполняется командой LINK (при этом должна вызываться 16-битная версия компоновщика LINK.EXE). Компоновщик LINK сгенерирует EXE-файл, который впоследствии необходимо преобразовать в СОМ-формат командой EXE2BIN:
link name.obj,,NUL,,,
exe2bin name.exe name.com
В результате работы компоновщика будет создан файл NAME.СОМ размером 11 байт. В результате запуска этого файла командный процессор сформирует PSP, загрузит программу в память и передаст управление ее первой команде.