Все функции DOS вызываются прерыванием 21h, при этом в AH содержится номер функции. Ниже везде, где есть слова "стандартный ввод", под ними подразумевается клавиатура, однако ввод может быть переопределен (например, из файла). Аналогично, "стандартный вывод" – экран, но вывод также может быть переопределен (например, в файл). ASCIIZ-строка (нуль-терминированная строка) – это строка символов, заканчивающаяся нулевым символом (код 00h).
1. Ввод символа с отображением. Прерывание 21h функция 01h. Вызов: AH=01h. Возвращает: AL=введенный символ. Действие: читает символ (возвращаемый в AL) со стандартного ввода (клавиатуры) и выводит его на стандартный вывод (экран). Если ввод был перенаправлен, то невозможно обнаружить EOF.
- если при вводе нажата Ctrl+C и BREAK=ON, то вызывается прерывание 23h;
- чтобы прочитать расширенные коды (например, клавиш F1-F12), надо вызвать функцию дважды. Первый раз возвращается 00h, затем – код клавиши.
2. Вывод символа. Прерывание 21h функция 02h. Вызов: AH=02h; DL=выводимый символ. Возвращает: ничего. Действие: выводит символ на стандартный вывод. Если вывод был перенаправлен, то невозможно обнаружить, что нет места на диске.
- если Ctrl+C после вывода символа, то вызавается прерывание 23h;
- если стандартный вывод не был перенаправлен, то символ Backspace (08h) перемещает курсор влево на одну позицию.
3. Прямой консольный ввод/вывод. Прерывание 21h функция 06h. Вызов: AH=06h; DL=действие: если DL=00h-FEh, то вывод; если DL=FFh, то ввод. Возвращает:
если вызов с DL=00h-FEh, то ничего;
если вызов с DL=FFh, то: если есть символ – ZF=0, AL=введенный символ
если нет символа – ZF=1.
Действие: используется, если нужно прочитать или записать все возможные символы и управляющие коды без действий ОС. Читает символ со стандартного ввода или записывает символ на стандартный вывод. Если вывод был перенаправлен, то невозможно обнаружить EOF или что нет места на диске.
- Никакой реакции на Ctrl+C;
- чтобы прочитать расширенные коды (например, клавиш F1-F12), надо вызвать функцию дважды. Первый раз возвращается 00h, затем – код клавиши.
4. Ввод символа без отображения. Прерывание 21h функция 07h. Вызов: AH=07h. Возвращает: AL=введенный символ. Действие: читает символ (возвращаемый в AL) со стандартного ввода (клавиатуры) без отображения на стандартном выводе (экране). Если нет символа, то ждет его появления. Если ввод был перенаправлен, то невозможно обнаружить EOF.
- Никакой реакции на Ctrl+C. Нужно использовать функцию 08h, если реакция требуется;
- чтобы прочитать расширенные коды (например, клавиш F1-F12), надо вызвать функцию дважды. Первый раз возвращается 00h, затем – код клавиши.
5. Ввод символа без отображения. Прерывание 21h функция 08h. Вызов: AH=08h. Возвращает: AL=введенный символ. Действие: читает символ (возвращаемый в AL) со стандартного ввода (клавиатуры) без отображения на стандартном выводе (экране). Если нет символа, то ждет его появления. Если ввод был перенаправлен, то невозможно обнаружить EOF.
- если при вводе нажата Ctrl+C и BREAK=ON, то вызывается прерывание 23h. Нужно использовать функцию 08h, если реакции не требуется;
- чтобы прочитать расширенные коды (например, клавиш F1-F12), надо вызвать функцию дважды. Первый раз возвращается 00h, затем – код клавиши.
6. Вывод строки. Прерывание 21h функция 09h. Вызов: AH=09h, DS:DX=сегмент:смещение строки. Возвращает: ничего. Действие: посылает строку символов на стандартный вывод. Если вывод был перенаправлен, то невозможно обнаружить, что нет места на диске.
- Строка должна заканчиваться на символ $(код 24h), который не выводится. Любые другие символы ASCII, включая управляющие, могут содержаться в строке. Для перевода курсора на начало новой строки нужно вывести строку, содержащую символы "перевод строки"/"возврат каретки":
string DB 10,13,'$'
или использовать прерывание 10h функцию 02h (см. 6.8.2.).
- Если Ctrl+C нажата на клавиатуре, то вызывается прерывание 23h.
7. Буферизованный ввод с клавиатуры. Прерывание 21h функция 0Ah. Вызов: AH=0Ah, DS:DX=сегмент:смещение буфера. Возвращает: ничего. Действие: читает строку символов со стандарного ввода, до появления символа возврата каретки (0Dh) и помещает в буфер (включая завершающий 0Dh). Символы отображаются на стандартном выводе. Если ввод был перенаправлен, то невозможно обнаружить EOF.
- Буфер, используемый этой функцией, имеет формат(см. табл. 6.4.):
Таблица 6.4.
Байт
Описание
Максимальное количество символов (устанавливается перед вызовом)
Количество реально прочитанных символов (устанавливается функцией после ее вызова)
2 и след.
Прочитанная строка, заканчивающаяся 0Dh
- Если буфер заполнился (больше символов, чем максимум), последующий ввод игнорируется и подается сигнал до тех пор, пока не нажата клавиша ENTER;
- Если при вводе нажата Ctrl+C и BREAK=ON, то вызывается прерывание 23h.
8. Проверка состояния ввода.Прерывание 21h функция 0Bh. Вызов: AH=0Bh. Возвращает: AL=00h, если нет символа; AL=FFh, если есть один или более символовhр. Действие: проверяет, есть ли в буфере стандартного ввода символ.
- Если при вводе нажата Ctrl+C и BREAK=ON, то вызывается прерывание 23h.
- Если есть символ, эта функция будет возвращать FFh, пока символ не считан функциями ввода (01h, 07h, и т.д.).
9. Очистка буфера и ввод. Прерывание 21h функция 0Ch. Вызов: AH=0Ch; AL=номер фунции, которая вызывается после очистки буфера; для AL=0Ah –DS:DX=сегмент:смещение буфера. Возвращает: если вызов с AL=01h, 07h, 08h то AL=прочитанный символ; если вызов с AL=0Ah, то ничего. Действие: очищает буфер стандартного ввода, затем вызывает одну из функций ввода (заданную в AL).
- Реакция на Ctrl+C (игнорирует или нет) зависит от вызываемой функции;
- Вызов с AL отличным от 01h, 06h, 07h, 08h, 0Ah просто очищает буфер.
10. Запись в файл или устройство. Прерывание 21h функция 40h. Действие: берет корректный дескриптор файла (от предыдущей операции создания или открытия файла), адрес буфера, длину в байтах, передает данные из буфера в файл и затем обновляет положение указателя в файле. Вызов: AH=40h; BX=дескриптор файла; CX=количество байт, которое надо записать; DS:DX=сегмент:смещение буфера. Возвращает: если нет ошибки: CF=0, AX=количество реально переданных байт; иначе – CF=1, AX=код ошибки.
- Если CF=0, но AX<CX, то часть буфера была записана или была ошибка. Это может быть из-за символа 1Ah (Ctrl+Z) в данных, если приемник – символьное устройство в режиме обработки символов, или из-за отсутствия места на диске, если приемник – файл;
- Если вызов с CX=0, то файл усекается или расширяется до текущей позиции указателя в файле;
11. Чтение из файла или устройства. Прерывание 21h функция 3Fh. Действие: берет корректный дескриптор файла (от предыдущей операции создания или открытия файла), адрес буфера, длину в байтах, передает данные из текущей позиции указателя в файле в буфер и затем обновляет положение указателя в файле. Вызов: AH=3Fh; BX=дескриптор файла; CX=количество байт, которое надо прочитать; DS:DX=сегмент:смещение буфера. Возвращает: если нет ошибки: CF=0, AX=количество реально переданных байт; иначе – CF=1, AX=код ошибки.
- Если CF=0, но AX<CX, то часть данных была прочитана до конца файла или была ошибка;
- Если CF=0, но AX=0, указатель в файле уже был в конце;
- Если читали с символьного устройства (например, с клавиатуры) в режиме обработки символов, то максимум одна строка может быть прочитана (т.е. до символа 0Dh или достижения указанной длины, что встретится раньше).
12. Установка указателя в файле. Прерывание 21h функция 42h. Действие: Устанавливает указатель в файле относительно начала, конца, или текущей позиции. Вызов: AH=42h; AL=код метода: 00h-относительно начала файла, 01h-относительно текущей позиции, 02h-относительно конца файла; BX=дескриптор файла; CX=старшая половина смещения; DX=младшая половина смещения. Возвращает: если нет ошибки: CF=0, DX=старшая половина новой позиции; AX=младшая половина новой позиции; иначе – CF=1, AX=код ошибки.
- Используется 32-битное значение смещения, чтобы установить новое значение указателя. Следующая операция записи/чтения будет производится с новой позиции указателя;
- Вызов с AL=02h со значением смещения может использоваться для получения размера файла;
- Используя методы 01h или 02h, можно установить указатель ДО начала файла, и ошибки не будет. Однако, при попытке записи/чтения будет зафиксирована ошибка;
- Вне зависимости от метода, DX и AX всегда содержат новое положение относительно начала файла.
13. Создание файла. Прерывание 21h функция 3Ch. Действие: берет путь в формате ASCIIZ, создает новый файл в указанном или текущем каталоге на указанном или текущем диске. Если файл существует, он усекается до нулевой длины. В любом случае, файл открывается и возвращается дескриптор, который может быть использован для последующего доступа к файлу. Вызов: AH=3Ch; CX=атрибуты файла (биты могут комбинироваться) см. табл. 6.5; DS:DX=сегмент смещение ASCIIZ-строки:
Таблица 6.5.
Бит
Атрибут файла
только чтение
Скрытый
Системный
метка тома
зарезервирован, должен быть 0
Архирный
6-15
зарезервирован, должен быть 0
Возвращает: если нет ошибки: CF=0, AX=дескриптор; иначе – CF=1, AX=код ошибки.
14. Открытие файла. Прерывание 21h функция 3Dh. Действие: берет путь в формате ASCIIZ, открывает файл в указанном или текущем каталоге на указанном или текущем диске. Возвращается дескриптор, который может быть использован для последующего доступа к файлу. Вызов: AH=3Dh; AL=атрибуты доступа (биты могут комбинироваться) см. табл. 6.6; DS:DX=сегмент смещение ASCIIZ-строки:
Таблица 6.6
Бит
Атрибут файла
0-2
режим доступа:
000=чтение
001=запись
010=запись/чтение
Зарезервирован, должен быть 0
4-6
Режим совместного доступа (MS-DOS 3.0 и выше):
000=режим совместимости
001=запрет всего
010=запрет записи
011=запрет чтения
100=не запрещать ничего
Флаг наследования (MS-DOS 3.0 и выше):
0=дочерний процесс наследует дескриптор
1=дочерний процесс ненаследует дескриптор
Возвращает: если нет ошибки: CF=0, AX=дескриптор; иначе – CF=1, AX=код ошибки.
15. Закрытие файла. Прерывание 21h функция 3Eh. Действие: берет дескриптор, сбрасывает все внутренние буферы, ассоциированные с файлом, на диск, закрывает файл и освобождает дескриптор для нового использования. Если файл был изменен, то время, дата и размер файла обновляются. Вызов: AH=3Eh; BX=дескриптор файла. Возвращает: если нет ошибки: CF=0, AX=дескриптор; иначе – CF=1, AX=код ошибки.
- Если случайно вызвать функцию с дескриптором 0, то стандартный ввод будет закрыт, и клавиатура "умрет". Поэтому перед вызовом следует проверять дескриптор на неравенство нулю.