Функция 5ah: Создать уникальный временный файл
Вход AH = 5ah
DS:DX = адрес строки ASCIIZ с диском и путем (заканчивается \)
CX = атрибут файла
Выход AX = код ошибки, если CF установлен
АХ = дескриптор файла (если нет ошибки)
DS:DX = (не изменяется) становится полным ASCIIZ-именем нового файла
Описание: Открывает (создает) файл с уникальным именем в каталоге, указанном строкой ASCIIZ, на которую указывает DS:DX. COMMAND.COM использует эту функцию, когда создает временные "канальные" файлы, используемые при переназначении ввода/вывода. Описание пути должно быть готово к присоединению в его конец имени файла. Вы должны обеспечить минимум 12 байт в конце строки. Сама строка должна быть содержать один из вариантов указания пути:
· "d:\путь\",0 (указаны диск и путь),
· "d:",0 (текущий каталог диска),
· "d:\",0 (корневой каталог диска),
· "",0 (текущие диск и каталог)
После возврата строка DS:DX будет дополнена именем файла.
Замечания: DOS создает имя файла из шестнадцатеричных цифр, получаемых из текущих даты и времени. Если имя файла уже существует, DOS продолжает создавать новые имена, пока не получит уникальное имя. Создаваемые таким способом файлы – по существу НЕ ВРЕМЕННЫЕ, и их следует удалять посредством функции DOS 41h , когда они не нужны.
Версии: Доступна, начиная с DOS 3.0
Функция 5bh: Создать новый файл
Вход AH = 5bh DOS 3.0+
DS:DX = адрес строки ASCIIZ с именем файла
CX = атрибут файла
Выход AX = код ошибки, если CF установлен
АХ = дескриптор файла, если ошибок нет
Описание: DS:DX указывает на строку ASCIIZ в форме: "d:\путь\имя_файла",0. Если диск и/или путь опущены, они принимаются по умолчанию. Этот вызов идентичен функции DOS 3ch CREATE, с тем исключением, что он вернет ошибку, если файл с заданным именем уже существует. Файл открывается для чтения/записи в совместимом Режиме Доступа.
Функция 5ch: Блокировать/разблокировать доступ к файлу
Вход AH = 5ch
AL = Подфункция:
0 - заблокировать область файла
1 - разблокировать ранее захваченную область
BX = дескриптор файла (handle)
CX:DX = смещение ((CX * 65536) + DX) от начала файла
SI:DI = длина блокируемой области ((SI * 65536) + DI) байтов
Выход AX = код ошибки, если CF установлен
Описание: Блокирует или освобождает доступ к участку файла, идентифицируемого дескриптором в BX. Область файла, начинающаяся по логическому смещению CX:DX и имеющая длину SI:DI, блокируется (захватывается) или разблокируется (освобождается). Смещение и длина обязательны. Разделение файлов Должно быть активизировано (командой SHARE), иначе функция вернет код ошибки "неверный номер функции" Блокировка действует на операции чтения, записи и открытия со стороны порожденного или конкурирующего процесса. При попытке такого доступа (и Режиме Доступа, определенном при OPEN как "режим разделения", который запрещает такой доступ), DOS отвергает операцию через вызов int 24h (обработчик критических ошибок) после трех попыток. DOS при этом выдает сообщение "Abort, Retry, Ignore". Рекомендуемое действие - НЕ пытаться читать файл и ожидать кода ошибки. Вместо этого попытайтесь заблокировать область и действуйте в соответствии с кодом возврата. Это позволяет избежать довольно неустойчивого состояния DOS, связанного с выполнением int 24h. Блокировка за концом файла не является ошибкой. Вы можете захватить весь файл, задав CX=0, DX=0, SI=0ffffh, DI=0ffffh и AL=0. При освобождении смещение и длина участка должны точно совпадать со смещением и длиной захваченного участка.
Замечания: Дублирование дескриптора через 45h или 46h дублирует и блокировки со смещением и длиной захваченного участка. Даже если во время OPEN выбран Режим Доступа Inherit, механизм блокировки не даст никаких привилегий доступа порожденным процессам, созданным функцией 4bh EXEC (они трактуются как отдельные). Важно, чтобы все блокировки файла были сняты до завершения программы. Если вы используете блокировку, особо отслеживайте вызовы int 23h (выход Ctrl-Break) и int 24h (выход по критической ошибке), чтобы снять блокировки до действительного завершения программы. Рекомендуется освобождать блокировки как можно скорее. Всегда блокируйте, обрабатывайте файл и освобождайте блокировку одной операцией. Версии: Доступна, начиная с DOS 3.0
Функция 62h: Дать адрес PSP
Вход AH = 62h DOS 3.0+
Выход BX = сегментный адрес PSP выполняемой программы
Описание: Эта функция возвращает в BX адрес PSP текущей программы. Используется, чтобы получить адрес параметров командной строки, адрес окружения DOS и другой полезной информации в PSP. Версии: Доступна, начиная с DOS 3.0
КОДЫ ОШИБОК DOS
1.5.1. Коды ошибок
(начиная с версии DOS 2.0, возвращаются в
AX, если установлен флаг переноса CF)
Ошибка | Значение | |
Hex | Dec | |
Неверный номер функции | ||
Файл не найден | ||
Путь не найден | ||
Слишком много открытых файлов | ||
Доступ отвергнут | ||
Неверный дескриптор (handle) | ||
Разрушены блоки управления памятью | ||
Недостаточно памяти | ||
Неверный адрес блока памяти | ||
0ah | Неверное окружение | |
0bh | Неверный формат | |
0ch | Неверный код доступа | |
0dh | Неверная дата | |
0eh | Не используется | |
0fh | Задан неверный диск | |
10h | Нельзя удалить текущий каталог | |
11h | не то же самое устройство | |
12h | Больше нет искомых файлов |
1.5.2. Дополнительные коды ошибок
(начиная с версии DOS
3.0, выдаются функцией 59h)
Ошибка | Значение | |
Hex | Dec | |
Нет ошибок | ||
13h | Попытка записи на защищенный диск | |
14h | Неизвестный идентификатор устройства | |
15h | Дисковод не готов | |
16h | Неизвестная команда | |
17h | Ошибка данных диска (ошибка контрольной суммы) | |
18h | Неверная длина структуры запросов | |
19h | Ошибка поиска на диске | |
1ah | Неизвестный тип носителя диска | |
1bh | Сектор не найден | |
1ch | Конец бумаги на принтере | |
1dh | Ошибка записи | |
1eh | Ошибка чтения | |
1fh | Общая ошибка | |
20h | Нарушение разделения файла | |
21h | Нарушение блокировки | |
22h | Неверная замена диска | |
23h | FCB недоступен (слишком много открытых FCB) | |
24h-49h | Резерв | |
50h | Файл уже существует | |
51h | Резерв | |
52h | Неизвестно что | |
53h | int 24h – сбой при обработке прерывания по критической ошибке |
Коды 13h – 1fh соответствуют ошибкам 0 – 0ср, передаваемых в регистре DI обработчику критических ошибок int 24h. Они также совпадают с кодами ошибок в AL для int 25h, int26h
1.5.3. Класс ошибки
Эти коды предоставляют дополнительную информацию, чтобы помочь вам обработать ошибку. Функция 59h возвращает значение класса ошибки в регистре BH.
Ошибка | Значение (возвращается в ВН функцией 59h) | |
Hex | Dec | |
Нет ресурсов: не хватает FCB, памяти, каналов, дескрипторов файлов и т. п. | ||
Временная ситуация: исчезнет со временем (например, блокировка файла) | ||
Проблема авторизации: Вы должны иметь более высокие полномочия | ||
Внутренняя ошибка: сбой DOS | ||
Ошибка оборудования | ||
Системная ошибка: сбой DOS | ||
Ошибка приложения: некорректный запрос, неверные параметры и т. п. | ||
Не найден запрошенный файл/элемент | ||
Неверный формат: испорчен файл ЕХЕ, плохой диск и т.п. | ||
0ah | Блокировка: файл/элемент захвачен другим пользователем |
0bh | Ошибка носителя: неверный диск, ошибка контроля четности и т. п. | |
0ch | Уже существует файл/элемент | |
0dh | Неизвестный класс: классификация не определена или на проходит |
1.5.4. Предлагаемое действие
Эти коды отражают подходящее действие по устранению ошибки. Идея состоит в том, чтобы сэкономить ваш код, не заставляя вас проверять коды ошибок в приложении. Вместо этого вы достигнете совместимости вверх, выполняя предлагаемые ниже действия. Функция 59h возвращает эти коды в регистре BL.
Ошибка | Значение (возвращается в ВL функцией 59h) | |
Hex | Dec | |
Повторить: повторите операцию несколько раз. Если ошибка повторяется, запросите пользователя, продолжить или закончить работу. | ||
Задержать повтор: подождите немного и повторите операцию. Если ошибка повторяется, запросите пользователя, продолжить или закончить работу. | ||
Ввод пользователя: если данные для DOS были введены пользователем, предложите ему повторить ввод (может быть неверный идентификатор диска или путь). | ||
Снять: снимите приложение. Можно выполнить операции завершения, какие, как закрытие файлов, обновление индексов, освобождение памяти и т. п. | ||
Немедленный выход: снимайте немедленно без попытки завершения. Система в подозрительном состоянии, и немедленный выход – лучшее продолжение. | ||
Игнорировать: ошибка ни на что не влияет | ||
Повторить после действия пользователя: требуется вмешательство пользователя (например, установка дискеты). После этого повторите операцию. |
1.5.5. Сфера ошибки
Эти коды служат для того, чтобы помочь вам определить место ошибки. Функция 59h возвращает эти коды в регистре CH.
Ошибка | Значение (возвращается в СН функцией 59h) | |
Hex | Dec | |
Неизвестно: не существует определенной области для привязки ошибки | ||
Блочное устройство: ошибка дискового или ленточного устройства | ||
Резерв | ||
Символьное устройство | ||
Память |
1.5.6. Версии DOS
Обработка ошибок совместима снизу вверх для всех версий DOS. Применимы следующие общие правила:
· DOS 1.x: индицирует некоторые ошибки, помещая в AL при возврате 0ffh.
· DOS 2.x: новые вызовы 2.x индицируют ошибки, устанавливая флаг CF=1 и помещая код ошибки в AX.
· DOS 3.x: вызовы 3.x по-прежнему помещают код ошибки в AX при CF=1, но нет гарантии, что будущие версии будут поступать так же. Советуем использовать функцию 59h для получения информации об ошибке.
ГЛАВА 2.
ПРИМЕРЫ ПРОГРАММ
2.1 РАБОТА С ЭКРАНОМ
2.1.1. Вывод текста
Задача: Вывести на середину пустого экрана мигающее слово "ТЕКСТ" текстовом режиме CGA 80 символов * 25 строк.
a) Используя функции DOS.
b) Используя функции BIOS.
c) Помещая символы непосредственно в экранную область.
а) Использование функций DOS
Assume CS: Code;, DS: Code
Code SEGMENT
org 100h
Start: mov ax,cs
mov ds,ax
; Установка видеорежима 03
mov ah,0 ; Функция 0
mov al,3 ; Режим 3
int 10h
; Вывод текста (мигание в ДОС нельзя)
mov ah,9 ; Функция 9
lea dx,text ; Смещение текста (DS)
int 21h
; Ожидание ввода клавиши пробела
loop1: mov ah,7 ; Функция 7 (нефильтрованный ввод без эха)
int 21h
cmp al,' ' ; Пробел ?
jnz loop1 ; Нет !
; Выход из программы
int 20h
text db 25 dup(0ah),0dh ; Очистка экрана
db 38 dup(20h),'ТЕКСТ' ; Вывод слова на середину
db 12 dup(0ah),0dh,'$' ; На середину экрана
Code ENDS
END Start
б. Использование функций BIOS
Assume CS: Code;, DS: Code
Code SEGMENT
org 100h
Start: mov ax,cs
mov ds,ax
; Установка видеорежима 3
mov ah,0 ; Функция 0
mov al,3 ; Режим 3
int 10h
; Очистка экрана и задание атрибута мигания
mov ah,6 ; Инициализация или прокрутка окна вверх
mov al,0 ; Очистка всего окна
mov bh,87h ; Установка атрибута мерцания
mov ch,0 ; Y лев. верхнего угла
mov cl,0 ; X лев. верхнего угла
mov dh,24 ; Y прав. нижнего угла
mov dl,89 ; X прав. нижнего угла
int 10h
; Установка позиции курсора
mov ah,2 ; Функция 2
mov bh,0 ; Страница 0
mov dh,12 ; Строка 12
mov dl,38 ; Колонка 38
int 10h
; Вывод текста
mov ah,0Eh ; Функция 0Eh
lea si,text ; Смещение текста (DS)
mov bl,7
loop2: cmp byte ptr [si],0 ; Проверка на конец текста
jz loop1 ; Выход
mov al,[si]
int 10h
inc si
jmp short loop2
; Ожидание ввода клавиши пробела
loop1: mov ah,0 ; Функция 0
int 16h
cmp al,' ' ; Пробел ?
jnz loop1 ; Нет !
; Выход из программы
int 20h
text db 'ТЕКСТ',0 ; Вывод слова на середину
Code ENDS
END Start
в. Непосредственный вывод в экранную область
Assume CS: Code;, DS: Code
Code SEGMENT
org 100h
Start: mov ax,cs
mov ds,ax
; Установка видеорежима 3
mov ah,0 ; Функция 0
mov al,3 ; Режим 3
int 10h
; Очистка экрана
mov ax,0b800h
mov es,ax ; ES = B800h
xor si,si ; Обнуление регистра-источника
xor di,di ; Обнуление регистра назначения
mov cx,2000 ; Инициализация счетчика
mov ax,0700h
rep stosw
; Вывод текста
lea si,text ; Смещение текста (DS)
mov di,2000 ; Начальная ячейка экр. памяти
mov ah,8fh ; Атрибут
loop2: cmp byte ptr [si],0 ; Проверка на конец текста
jz loop1 ; Выход
mov al,[si]
mov es:[di],ax ; На экран
inc si
inc di
inc di
jmp short loop2
; Ожидание ввода клавиши пробела
loop1: mov ah,0 ; Функция 0
int 16h
cmp al,' ' ; Пробел ?
jnz loop1 ; Нет !
; Выход из программы
int 20h
text db 'ТЕКСТ',0 ; Вывод слова на середину
Code ENDS
END Start
2.1.2. Вывод графических образов
Написать программу, которая в графическом режиме CGA 4 * 320 * 200 рисует голубыми линиями рамку по краю экрана, а в центре рисует закрашенный сиреневый пря моугольник размером 40 * 40 точек
Assume CS: Code;, DS: Code
Code SEGMENT
org 100h
Start: jmp start1
color db 0 ; Текущий цвет
x1 dw 0 ; Координата Х1
y1 dw 0 ; Координата У1
x2 dw 0 ; Координата Х2
y2 dw 0 ; Координата У2
start1: ; Установка видеорежима
mov ah,0 ; Функция установки видеорежима
mov al,4 ; Граф. реж. CGA 320 * 200 точек
int 10h
; Построение голубой рамки
; Горизонтали
mov al,1 ; Голубой цвет
mov x1,0
mov x2,319
mov y1,0
call lineh ; Верхняя горизонталь
mov x1,0
mov x2,319
mov y1,199
call lineh ; Нижняя горизонталь
; Вертикали
mov x1,0
mov y1,0
mov y2,199
call linev ; Левая вертикаль
mov x1,319
mov y1,0
mov y2,199
call linev ; Правая вертикаль
; Построение прямоугольника
mov al,2 ; Сиреневый цвет
mov x1,140
mov y1,80
mov x2,180
mov y2,120
call bar
call kbin
int 20h
; Ввод с клавиатуры
kbin proc near
mov ah,0 ; Функция 0
int 16h ; клавиатурного прерывания
ret
kbin endp
; Построение закрашенного прямоугольника
; Х1,Y1 - координаты левого верхнего угла
; X2,Y2 - координата првого нижнего угла
bar proc near
mov cx,x1
cmp cx,x2 ; Сравнение начала с концом
jc bar1 ; x1 < x2
ret ; Выход при нулевой ширине прямоуг.
bar1: mov dx,y1 ; Начало линии
cmp dx,y2 ; Сравнение начала с концом
jc bar2 ; y1 < y2
ret ; Выход при нулевой высоте прямоуг.
; Построение CX, DX - левый верхний угол
bar2: mov bp,y2
sub bp,dx
inc bp
bar3: call lineh
inc word ptr y1
dec bp
jnz bar3
ret
bar endp
; Построение вертикальной линии
; Х1 - координата X
; Y1 - координата Y начала линии
; X2 - координата Y конца линии
linev proc near
mov cx,x1
mov dx,y1 ; Начало линии
cmp dx,y2 ; Сравнение начала с концом
jnz lv1 ; Длина не нулевая
ret ; Выход при нулевой длине
lv1: jc lv2 ; Начало меньше конца
; Здесь начало (CX) больше конца (X2)
sub dx,y2
inc dx
mov bx,dx ; Длина линии
mov dx,y2 ; Бывший конец линии
jmp short lv3
lv2: mov bx,y2 ; Конец (CX = начало)
sub bx,y1 ; Минус начало
inc bx ; Длина
lv3: call pixel
inc dx
dec bx
jnz lv3
ret
linev endp
; Построение горизонтальной линии
; Y1 - координата Y
; X1 - координата Х начала линии
; X2 - координата Х конца линии
lineh proc near
mov dx,y1
mov cx,x1 ; Начало линии
cmp cx,x2 ; Сравнение начала с концом
jnz lh1 ; Длина не нулевая
ret ; Выход при нулевой длине
lh1: jc lh2 ; Начало меньше конца
; Здесь начало (CX) больше конца (X2)
sub cx,x2
inc cx
mov bx,cx ; Длина линии
mov cx,x2 ; Бывший конец линии
jmp short lh3
lh2: mov bx,x2 ; Конец (CX = начало)
sub bx,x1 ; Минус начало
inc bx ; Длина
lh3: call pixel
inc cx
dec bx
jnz lh3
ret
lineh endp
; Построение точки текущего цвета
; CX - координата Х
; DX - координата Y
pixel proc near
push bx
mov ah,0ch ; Функция построения графич. точки
mov bh,0 ; Видеостраница
int 10h
pop bx
ret
pixel endp
code ends
END Start ; Указание точки входа в программу
2.1.3. Построение прямых
Написать программу, которая строит линию с наклоном от 0 до 45 градусов. Построение произвольной прямой:
· | tg = | Y2 – Y1 | ||
x2,y2 | X2 – X1 | |||
· | Погрешность: | |||
x1,y1 | EPS = Yист - Y | |||
Вначале EPS = 0 (т.к. начальные точки совпадают). С каж дым шагом по Х погрешность возрастает на tg. Условие для приращения Y -0.5 < EPS £ 0.5.
Построение прямой:
tg = (y2-y1)/(x2-x1);
eps = 0;
y = y1;
for (x=x1; x<=x2; x++)
{ pixel (x,y);
eps+=tg;
if(eps > 0.5) {y++;eps--;}
}