На этом шаге мы приведем пример программы, иллюстрирующей применение функций разширенной версии DOS.
Реализуем программу, приведенную на шаге 60, с помощью функций расширенной версии DOS.
TITLE Работа с файлами в расширенной версии DOS. ;Программа сделана как EXE-файл. ;------------------------------- EXTRN Vvod:FAR,Vyvod:FAR,Clear:FAR,Write_Str:FAR,Cursor:FAR ;----- Сегмент стека StackSg SEGMENT PARA STACK 'Stack' DW 256 DUP(?) StackSg ENDS ;----- Сегмент данных DataSg SEGMENT PARA PUBLIC FILE DB 'E:\Arkady\Site\Works\proba1.dat',0 HANDLE DW ? ;Файловый номер DTA DW ? ;Область для размещения значения. STR1 DB "Ошибка при создании файла. Программа завершена.$" STR2 DB "Задайте целое число (0 - признак конца ввода): $" STR3 DB "Содержимое файла: $" STR4 DB "Задайте номер элемента (0 - выход): $" STR5 DB "Элемента с таким номером нет!$" STR6 DB "Элемент с этим номером: $" STR7 DB "Новое значение элемента: $" KOL DW ? ;Количество элементов в файле. PUNKT DB ? ;Номер выбранного пункта меню. ;------- Главное меню (длина каждого элемента - 48 символов). ELEM1 DB " Г Л А В Н О Е М Е Н Ю : $" ELEM2 DB " Создание файла ............................. 1$" ELEM3 DB " Просмотр файла ............................. 2$" ELEM4 DB " Вывод элемента с заданным номером .......... 3$" ELEM5 DB " Изменение элемента с заданным номером ...... 4$" ELEM6 DB " Выход ...................................... 0$" ELEM7 DB " Укажите номер пункта ....................... $" KOLP DW 7 ;Количество пунктов меню. DLINA DW 48 ;Длина пункта меню. RAB1 DW ? ;Рабочая ячейка. RAB2 DW ? ;Рабочая ячейка. DataSg ENDS ;----- Сегмент кода CodeSg SEGMENT PARA PUBLIC ASSUME CS: CodeSg, DS:DataSg, SS: StackSg Begin PROC FAR ;Пролог EXE-файла. PUSH DS XOR AX,AX PUSH AX MOV AX,DataSg MOV DS,AX ;Конец пролога. @N: ;---------------- Главное меню. CALL Menu ; Вывод меню. CMP PUNKT,0 JE @ET ; Выход из программы. CMP PUNKT,1 JE @P1 ; Создание файла. CMP PUNKT,2 JE @P2 ; Просмотр файла. CMP PUNKT,3 JE @P3 ; Вывод элемента с заданным номером. CMP PUNKT,4 JE @P4 ; Изменение элемента с заданным номером. JMP @N @P1: ;---------------Создание файла. CALL Clear ; Очистка экрана. MOV AH,3CH ; Запрос на создание MOV CX,00 ; обычного файла. LEA DX,FILE ; ASCIIZ строка. INT 21H ; Вызов DOS-прерывания. JC ERROR ; Переход по ошибке. MOV HANDLE,AX ; Сохранение файлового номера. CALL Zapoln ; Обращение к процедуре заполнения файла. JMP @N ; Переход на меню. ERROR: MOV DX,0000h CALL Cursor ; Установка курсора. LEA DX,STR1 CALL Write_Str ; Вывод строки. RET ; Конец программы. @P2: ;---------------Просмотр содержимого файла. CALL Clear ; Очистка экрана. MOV DX,0000h CALL Cursor ; Установка курсора. LEA DX,STR3 CALL Write_Str ; Вывод строки. CALL Vyvod_File ; Обращение к процедуре вывода содержимого файла. MOV AH,1 ; Задержка. INT 21H JMP @N ; Переход на меню. @P3: ;---------------Обращение к процедуре вывода элемента. CALL Vyv_Elem JMP @N ; Переход на меню. @P4: ;---------------Обращение к процедуре изменения элемента. CALL Izm_Elem JMP @N ; Переход на меню. @ET: ;-------------- Выход из программы. MOV AH,3EH ; Запрос на закрытие файла. MOV BX,HANDLE ; Файловый номер. INT 21H ; Вызов DOS-прерывания. RET Begin ENDP ;========== ПРОЦЕДУРА ИЗМЕНЕНИЯ ЭЛЕМЕНТА ============== Izm_Elem PROC @V00: CALL Clear ; Очистка экрана. MOV DX,0000h CALL Cursor ; Установка курсора. LEA DX,STR4 CALL Write_Str ; Вывод строки-запроса номера элемента. CALL Vvod ; Ввод номера элемента. CMP BX,KOL ; Сравниваем с количеством элементов. JG @NOO ; Нет элемента с таким номером. CMP BX,0 JL @NOO JNE @V10 RET ; Выход при 0. @V10: ADD BX,BX ; Вычисляем смещение. SUB BX,2 MOV RAB1,BX ; Запоминаем его в ячейке RAB1. MOV AH,42H ; Установка указателя MOV AL,00 ; от начала файла. MOV BX,HANDLE ; Установка файлового номера. MOV CX,00 ; Смещение на MOV DX,RAB1 ; BX байтов. INT 21H ; Вызов DOS-прерывания. MOV DX,0100h CALL Cursor ; Установка курсора. LEA DX,STR7 CALL Write_Str ; Вывод строки-запроса значения элемента. CALL Vvod ; Запрос на ввод элемента. MOV DTA,BX ; Размещение значения в DTA. MOV AH,40H ; Запрос записи. MOV BX,HANDLE ; Файловый номер. MOV CX,2 ; Длина записи. LEA DX,DTA ; Адрес области вывода. INT 21H ; Вызов DOS-прерывания. JMP @V00 ; Переход на начало. @NOO: MOV DX,0400h CALL Cursor ; Установка курсора. LEA DX,STR5 CALL Write_Str ; Вывод строки c сообщением об отсутствии элемента. MOV AH,1 ; Задержка. INT 21H JMP @V00 ; Переход на начало. Izm_Elem ENDP ;========== ПРОЦЕДУРА ВЫВОДА ЭЛЕМЕНТА ============== Vyv_Elem PROC @V0: CALL Clear ; Очистка экрана. MOV DX,0000h CALL Cursor ; Установка курсора. LEA DX,STR4 CALL Write_Str ; Вывод строки-запроса номера элемента. CALL Vvod ; Ввод номера элемента. CMP BX,KOL ; Сравниваем с количеством элементов. JG @NO ; Нет элемента с таким номером. CMP BX,0 JL @NO JNE @V1 RET ; Выход при 0. @V1: ADD BX,BX ; Вычисляем смещение. SUB BX,2 MOV RAB1,BX ; Запоминаем его в ячейке RAB1. MOV AH,42H ; Установка указателя MOV AL,00 ; от начала файла. MOV BX,HANDLE ; Установка файлового номера. MOV CX,00 ; Смещение на MOV DX,RAB1 ; BX байтов. INT 21H ; Вызов DOS-прерывания. MOV AH,3FH ; Запрос на чтение. MOV BX,HANDLE ; Файловый номер. MOV CX,2 ; Длина записи. LEA DX,DTA ; Адрес области ввода. INT 21H ; Вызов DOS-прерывания. MOV DX,0100h CALL Cursor ; Установка курсора. LEA DX,STR6 CALL Write_Str ; Вывод строки-вывода элемента. MOV BX,DTA ; Размещение прочитанного в BX. CALL Vyvod ; Вывод на экран MOV AH,1 ; Задержка. INT 21H JMP @V0 ; Переход на начало. @NO: MOV DX,0400h CALL Cursor ; Установка курсора. LEA DX,STR5 CALL Write_Str ; Вывод строки c сообщением об отсутствии элемента. MOV AH,1 ; Задержка. INT 21H JMP @V0 ; Переход на начало. Vyv_Elem ENDP ;========== ПРОЦЕДУРА ЗАПОЛНЕНИЯ ФАЙЛА ============== Zapoln PROC MOV KOL,0 ; Обнуление количества элементов. @START: CALL Clear ; Очистка экрана. MOV DX,0000h CALL Cursor ; Установка курсора. LEA DX,STR2 CALL Write_Str ; Вывод строки-приглашения. CALL Vvod ; Ввод числа. CMP BX,0 ; Проверка на выход. JE @EXIT MOV DTA,BX ; Размещение числа в DTA. MOV AH,40H ; Запрос записи. MOV BX,HANDLE ; Файловый номер. MOV CX,2 ; Длина записи. LEA DX,DTA ; Адрес области вывода. INT 21H ; Вызов DOS-прерывания. INC KOL ; Количество элементов увеличиваем на 1. JMP @START @EXIT: ; Выход. MOV AH,3EH ; Запрос на закрытие файла. MOV BX,HANDLE ; Файловый номер. INT 21H ; Вызов DOS-прерывания. MOV AH,3DH ; Запрос на открытие. MOV AL,02 ; Чтение и запись. LEA DX,FILE ; Строка в формате ASCIIZ. INT 21H ; Вызов DOS-прерывания. MOV HANDLE,AX ; Сохранение файлового номера. RET Zapoln ENDP ;========== ПРОЦЕДУРА ВЫВОДА СОДЕРЖИМОГО ФАЙЛА ============== Vyvod_File PROC MOV DX,0100h CALL Cursor ; Установка курсора. ; Перемещение указателя в начало файла. MOV AH,42H ; Установка указателя MOV AL,00 ; от начала файла. MOV BX,HANDLE ; Установка файлового номера. MOV CX,00 ; Смещение на MOV DX,00 ; 0 байтов. INT 21H ; Вызов DOS-прерывания. @PROD: MOV AH,3FH ; Запрос на чтение. MOV BX,HANDLE ; Файловый номер. MOV CX,2 ; Длина записи. LEA DX,DTA ; Адрес области ввода. INT 21H ; Вызов DOS-прерывания. CMP AX,0 ; Прочитано 0 байтов? JE @EXT; ; Да - выход. MOV BX,DTA ; Размещение прочитанного в BX. CALL Vyvod ; Вывод на экран MOV AH,2 MOV DL,' ' ; Вывод пробела (разделителя между числами). INT 21H JMP @PROD @EXT: ; Выход. RET Vyvod_File ENDP ;========== ГЛАВНОЕ МЕНЮ ============== Menu PROC PUSH CX PUSH DX CALL Clear ; Очистка экрана. MOV DX,0000 ; Начальная позиция курсора. MOV RAB1,DX ; Сохраним значение DX (позицию курсора). LEA DX,ELEM1 ; Адрес первого пункта меню. MOV CX,KOLP ; Количество пунктов меню. MOV RAB2,DX ; Сохраним значение DX (адрес начала меню). @POWT: MOV DX,RAB1 ; Восстановим сохраненную позицию курсора. CALL Cursor ; Установка курсора. INC DH ; Увеличим номер строки. MOV RAB1,DX ; Сохраним значение DX (позицию курсора). MOV DX,RAB2 ; Восстановим сохраненный адрес начала меню. CALL Write_Str ; Вывод пункта меню. ADD DX,DLINA ; Получм адрес следующего пункта меню. MOV RAB2,DX ; Сохраним значение DX (адрес пункта меню). LOOP @POWT MOV AH,1 INT 21H SUB AL,30H MOV PUNKT,AL ; Сохраняем номер выбранного пункта. POP DX POP CX RET Menu ENDP CodeSg ENDS END Begin
На следующем шаге мы рассмотрим еще несколько функций, предназначенных для работы с файлами в базовой версии DOS.