Шаг 65.
Функции расширенной версии DOS для работы с файлами. Пример программы

    На этом шаге мы приведем пример программы, иллюстрирующей применение функций разширенной версии 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.




Предыдущий шаг Содержание Следующий шаг