Какой параметр функции dos 42h часто используется для определения длины файла

Обновлено: 03.07.2024

Все эти функции относятся к расширенной версии DOS, где обращение к файлам осуществляется с помощью дескриптора. Дескриптор или логический номер файла, присваивается операционной системой файлу в результате создания или открытия файла, заданного в формате ASCIIZ-строки. ASCIIZ-строка - символьная строка, завершающаяся нулем. Дескриптор файла записывается в регистр АХ и его следует сохранить в ячейке памяти.

Первые пять номеров (0-4) присвоены стандартным устройствам:

0 - стандартный ввод (CON).

1 - стагндартный вывод (CON).

2 - стандартная ошибка (CON).

3 - стандартный вспомогательный порт (AUX).

4 - стандартный принтер (PRN).

Мы можем использовать дескриптор 0 для ввода с клавиатуры, дескрипторы 1 или 2 - для вывода на экран.

При работе с файлами успешная операция устанавливает флаг CF в 0. Если операция не выполнилась, то флаг CF устанавливается в 1, а в регистр AX помещается код ошибки.

ошибка номера функции

путь доступа не найден

открыто слишком много файлов

доступ не разрешен

ошибка файлового номера

блок управления памятью разрушен

ошибка кода доступа

попытка удалить оглавление

не то устройство

нет больше файлов

Функции 3Ch и 5Bhпозволяют создать файл, с заданной спецификацией (путь и имя файла в формате ASCIIZ-строки). Различие функций в том, что функция 3Ch уничтожает имеющийся файл и создает новый с тем же именем, а функция 5Bh завершается с CF=1, если файл с таким именем существует.

; в сегмент данных поместить имя файла и зарезервировать ячейку для дескриптора

fname DB 'F1.TXT',0

mov AH, 3Ch ; запрос на создание

mov CX, 0 ; обычного файла

lea DX, fname ; адрес имени файла

jc err ; переход по ошибке

mov handle, AX; сохранить дескриптор

В этом примере в регистр CX заносится атрибут файла. Могут использоваться следующие атрибуты:

01h - файл только для чтения

02h - скрытый файл

04h - системный файл

Функция 3Dh- позволяет открыть уже имеющийся файл.

mov AH, 3Dh ; функция открытия файла

mov AL, 02 ; для ввода-вывода

При открытии файла в регистр AL заносится код доступа:

0 - открыть файл только для ввода;

1 - открыть файл только для вывода;

2 - открыть файл для ввода и вывода.

Функция 42hиспользуется для организации прямого доступа к произвольному месту файла. Указатель можно установить на начало файла (AL=0), в текущее положение (AL=1) и в конце файла (AL=2). Кроме того, значение смещения указателя (со знаком) заносится в регистры CX (старшая половина) и DX (младщая половина).

mov AH, 42h ; установить указатель

mov AL, 2 ; на конец файла

Функция 3Fhиспользуется для чтения из файла или устройства. При попытке чтения за концом файла AX=0.

mov AH, 3Fh ; функция чтения

mov BX, handle ; установить дескриптор

mov CX, 80 ; сколько читать

lea DX, buf ; и куда

mov CX, AX ; сколько фактически прочитали

Функция 40hиспользуется для записи в файл или на устройство.

mov AH, 40h ; функция записи

mov CX, 80 ; сколько писать

lea DX, buf ; откуда

Функция 43hиспользуется для получения (AL=0) или установки (AL=1) атрибутов файла.

mov AH, 43h ; функция работы с атрибутами

mov AL, 1 ; установка атрибутов

mov CX, 1 ; "только для чтения"

mov DX, offset fname ; адрес имени файла

Функция 56hиспользуется для переименования файла.

; настроить сегментный регистр ES на сегмент данных

mov AH, 56h ; функция переименования

mov DX, offset oldname ; адрес старого имени

mov DI, offest newname ; адрес нового имени

; в сегмент данных

oldname db 'fl.txt',0

newnamt db 'newf.txt',0

Функция 57hиспользуется для получения (AL=0) и установки (AL=1) даты и времени создания файла. Время записывается в регистр СХ и вычисляется по формуле:

CX= часы*2048+ минуты*32+секунды/2

Дата записывается в регистр DX и вычисляется по формуле:

; изменить время и дату создания файла

mov AH, 57h ; функция даты/времени

mov AL, 1 ; установить дату/время

mov BX, hаndle ; установить дескриптор

mov CX, 0 ; очистить cx

or CX, seс ; добавить секунды

or CX, min ; добавить минуты

or CX, hour ; добавить часы

xor DX, DX ; очистить DX

or DX,day ; добавить день

or DX, mon ; добавить месяц

or DX, year ; добавить год

; в сегмент данных

sec DW 6/2 ; 6 секунд

min DW 15 * 32 ; 15 минут

hour DW 16*2048 ; 16 часов

day DW 25 ; 25 число

mon DW 3*32 ; Март

year DW 25*512 ; 25 лет от 1980г, т.е. 2005 г.

Функция 3Ehиспользуется для закрытия файла. Эта операция необходима для коррекции оглавления и таблицы FAT.

mov AH, 3Eh ; функция закрытия

Функция 41hиспользуется для удаления файлов (за исключением файлов с атрибутом 'только чтение')

mov AH, 41h ; функция удаления

lea DX, fname ; адрес имени файла

int 21h ; вызов DOS

Работа с файлами может состоять из нескольких этапов:

1) Создания и открытие файла;

2) Установить указатель;

3) Определение длины файла;

4) Чтение нужного байта, блока,з апись байта, блока, до полнение файла;

5) Закрытие файла;

6) Удаление файла.

При разработке программы не все этапы необходимы, а также они могут следовать в другом порядке. При чтении нужного байта можно указать либо номер байта, либо значение байта и определить его номер или просто найти его.

Пример. Прочитать 10-й байт, открыть файл для чтения/записи

; установить указатель на 10 байт

mov AH, 42h ; установить указатель

mov AL, 00 ; на начало файла

mov DX, 10 ; на 10-й байт

; Прочитать нужный байт

; в сегмент данных

Пример 2. Найти символ "а" и определить его номер

;определить длину файла

mov AH, 42h ; установить указатель

mov AL, 2 ; на конец файла

mov CX, 00 ; старшая половина смещения

mov DX, 00 ; младшая половина смещения

mov FLEN, AX ; запомнить длину файла

;установить указатель на начало файла

;прочитать файл в bufin

;поиск символа "а"

cld ; поиск осуществляется слева направо

mov CX, FLEN ; длина файла

mov AL, 'A' ; искомый символ

lea DI, BUFIN ; адрес строки

repne scasb ; сканировать

jnz m ; символ найден?

dec DI ; да - уменьшить адрес

. ; вывести номер на экран m: .

Основная литература – 2[131-134,140-150,182-187], 3[85-94, 103-119]

Контрольные вопросы.

1. Чем отличаются функции 1, 7, 8 int 21h?

2. Что записывается в первый и во второй байт буфера при использовании ф.0Ah int 21h?

3. Как выполняется ввод при нажатии функциональной клавиши?

4. Чем отличается выполнение ф.0 int 16h и ф.7 int 21h?

5. Чем отличаются ф.0Ah и ф.3Fh int 21h?

6. С какого байта в буфере начинаются данные после использования ф.0Ah int 21h?

7. Чему равно значение последнего байта строки после использования ф.0Ah int 21h?

8. Фунцкии вывода символа на экран.

9. Функции вывода строки на экран.

10. Как определяется конец строки при использовании ф.9 и ф.40h int 21h?

11. Какие функции не перемещают курсор при выводе символа?

12. Какая функция вывода на дисплей меняет атрибут символа?

13. Что такое дескриптор файла?

14. Что такое ASCIIZ строка?

15. Дескрипторы стандартного ввода и стандартного вывода.

16. Как определяется успешность завершения какой-либо файловой операции?

17. Атрибуты файла.

18. Коды доступа при открытии файла.

19. Как определить длину файла?

20. Что делает функция закрытия файла?

21. Какие файлы нельзя удалить с помощью функции 41h?

Лабораторная работа 7. Разработка графического приложения для Windows

Цель работы. изучить основы программирования в среде Win32

Изучить процедуру главного окна

Изучить используемые в программе API-функции

Изменить параметры функции GetMessageA

Изменить параметры функции CreateWindowExA

6. Изменить главную процедуру окна WNDPROC

Методические рекомендации по выполнению лабораторной работы

Рассмотрим простую программу графического приложения. Разберите ее внимательно – она будет фундаментом, на котором мы будем строить дальнейшее рассмотрение.

Прежде всего обратите внимание на директиву INCLUDELIB. В пакете TASM32 довольно много разных библиотек. Для данного примера необходима: import32.lib. При наборе текста программы нужно изменить путь к библиотеке.

Сначала определяются константы и внешние библиотечные процедуры. В действительности все эти определения можно найти в include-файлах, прилагаемых к пакету TASM32. Мы не будем использовать стандартные include-файлы, т.к. так удобнее понять технологию программирования.

Выполните набор программы в блокноте или в любом другом простом текстовом редакторе. Чтобы получить загружаемый модуль, выполните следующие команды:

TASM32 /ml prog.asm

TLINK32 –aa prog.obj

.MODEL FLAT, stdcall

WM_DESTROY equ 2

WM_CREATE equ 1

WM_LBUTTONDOWN equ 201h

WM_RBUTTONDOWN equ 204h

CS_VREDRAW equ 1h

CS_HREDRAW equ 2h

CS_GLOBALCLASS equ 4000h

WS_OVERLAPPEDWINDOW equ 000CF0000H

style equ CS_HREDRAW + CS_VREDRAW + CS_GLOBALCLASS

; идентификатор стандартной иконки

IDI_APPLICATION equ 32512

IDC_CROSS equ 32515

; режим показа окна - нормальный

SW_SHOWNORMAL equ 1

; прототипы внешних процедур

EXTERN MessageBoxA: NEAR

EXTERN CreateWindowExA: NEAR

EXTERN DefWindowProcA: NEAR

EXTERN DispatchMessageA: NEAR

EXTERN ExitProcess: NEAR

EXTERN GetMessageA: NEAR

EXTERN GetModuleHandleA: NEAR

EXTERN LoadCursorA: NEAR

EXTERN LoadIconA: NEAR

EXTERN PostQuitMessage: NEAR

EXTERN RegisterClassA: NEAR

EXTERN ShowWindow: NEAR

EXTERN TranslateMessage: NEAR

EXTERN UpdateWindow: NEAR

; директивы компоновщику для подключения библиотек

CLSSTYLE DD ? ; стиль окна

CLWNDPROC DD ? ; указатель на процедуру окна

CLSCEXTRA DD ? ; информация о доп. байтах для данной структуры

CLWNDEXTRA DD ? ; информация о доп. байтах для окна

CLSHINSTANCE DD ? ; дискриптор приложения

CLSHICON DD ? ; идентификатор иконы окна

CLSHCURSOR DD ? ; идентификатор курсора окна

CLBKGROUND DD ? ; идентификатор кисти окна

CLMENUNAME DD ? ; имя-идентификатор меню

CLNAME DD ? ; специфицирует имя класса окна

_DATA SEGMENT DWORD PUBLIC USE32 'DATA'

HINST DD 0 ; здесь хранится дескриптор приложения

TITLENAME DB 'Простой пример 32-битного приложения',0

CLASSNAME DB 'CLASS32',0

MES1 DB 'Вы нажали левую кнопку мыши',0

MES2 DB 'Выход из программы. Пока!',0

_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'

; получить дескриптор приложения

; заполнить структуру окна

MOV [WC.CLSSTYLE], style

MOV [WC.CLWNDPROC], OFFSET WNDPROC

MOV [WC.CLSCEXTRA], 0

MOV [WC.CLWNDEXTRA], 0

MOV [WC.CLSHICON], EAX

MOV [WC.CLSHCURSOR], EAX

MOV [WC.CLBKGROUND],17 ; цвет окна

MOV DWORD PTR [WC.CLMENUNAME], 0

MOV DWORD PTR [WC.CLNAME], OFFSET CLASSNAME

PUSH 400 ; DY - высота окна

PUSH 400 ; DX - ширина окна

PUSH 100 ; Y - координата левого верхнего угла

PUSH 100 ; X - координата левого верхнего угла

PUSH OFFSET TITLENAME ; имя окна

PUSH OFFSET CLASSNAME ; имя класса

; проверка на ошибку

MOV [NEWHWND], EAX

CALL ShowWindow ; показать созданное окно

PUSH OFFSET MSG

PUSH OFFSET MSG

PUSH OFFSET MSG

; выход из программы (закрыть процесс)

; расположение параметров в стеке

CMP DWORD PTR [EBP+0CH], WM_DESTROY

CMP DWORD PTR [EBP+0CH], WM_CREATE

CMP DWORD PTR [EBP+0CH], WM_LBUTTONDOWN ; левая кнопка

CMP DWORD PTR [EBP+0CH], WM_RBUTTONDOWN ; правая кнопка

; нажатие правой кнопки приводит к закрытию окна

; нажатие левой кнопки мыши

PUSH OFFSET CAP

PUSH OFFSET MES1

PUSH DWORD PTR [EBP+08H]

PUSH DWORD PTR [EBP+14H]

PUSH DWORD PTR [EBP+10H]

PUSH DWORD PTR [EBP+0CH]

PUSH DWORD PTR [EBP+08H]

PUSH OFFSET CAP

PUSH OFFSET MES2

PUSH DWORD PTR [EBP+08H] ; дескриптор окна

Основная литература – 557

Контрольные вопросы.

Какие API-функции используются в программе?

Какие структуры используются в программе?

Структура графического приложения.

Лабораторная работа 8. Консольные приложения

Цель работы. Изучение основ применения API функции для консольных приложений.

Изменить размер окна консоли.

Поменять заголовок окна консоли.

Изменить позиции курсора.

Поменять цветовые атрибуты текста.

Разобрать алгоритм работы процедур NUMPAR и GETPAR.

Методические рекомендации по выполнению лабораторной работы

Для создания консоли используем функцию AllocConsole. По завершении программы консоль освобождается автоматически или с помощью функций FreeConsole.

Следует отметить, что один процесс может иметь только одну консоль, поэтому выполнение в начале программы FreeConsole обязательно.

Для чтения из буфера консоли используется функция ReadConsole.

Установить позицию курсора в консоли можно при помощи функции SetConsoleCursorPosition.

Установить цвет выводимых букв можно с помощью функции SetConsoleTextAttribute.

Для определения заголовка окна консоли используется функция SetConsoleTitle.

Функция CharToOem используется для перевода DOS-кодировки в Windows-кодировку.

Большинство консольных функций при правильном их завершении возвращает ненулевое значение. В случае ошибки в EAX помещается ноль.

Пример создания собственной консоли

.MODEL FLAT, stdcall

STD_OUTPUT_HANDLE equ -11

STD_INPUT_HANDLE equ -10

FOREGROUND_BLUE equ 1h ; синий цвет букв

FOREGROUND_GREEN equ 2h ; зеленый цвет букв

FOREGROUND_RED equ 4h ; красный цвет букв

FOREGROUND_INTENSITY equ 8h ; повышенная интенсивность

BACKGROUND_BLUE equ 10h ; синий цвет фона

BACKGROUND_GREEN equ 20h ; зеленый цвет фона

BACKGROUND_RED equ 40h ; красный цвет фона

BACKGROUND_INTENSITY equ 80h ; повышенная интенсивность

COL1 = 2h + 8h ; цвет выводимого текста

COL2 = 1h + 2h + 8h ; цвет выводимого текста 2

; прототипы внешних процедур

EXTERN GetStdHandle: NEAR

EXTERN WriteConsoleA: NEAR

EXTERN SetConsoleCursorPosition: NEAR

EXTERN SetConsoleTitleA: NEAR

EXTERN FreeConsole: NEAR

EXTERN AllocConsole: NEAR

EXTERN CharToOemA: NEAR

EXTERN SetConsoleCursorPosition: NEAR

EXTERN SetConsoleTextAttribute: NEAR

EXTERN ReadConsoleA: NEAR

EXTERN SetConsoleScreenBufferSize: NEAR

EXTERN ExitProcess: NEAR

; директивы компоновщику для подключения библиотек

_DATA SEGMENT DWORD PUBLIC USE32 'DATA'

STR1 DB 'Введите строку: ', 13, 10, 0

STR2 DB 'Простой пример работы консоли', 0

LENS DD ? ; количество выведенных символов

_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'

PUSH OFFSET STR1

PUSH OFFSET STR1

; вначале освободить уже существующую

; получить HANDL1 ввода

; получить HANDL вывода

; установить новый размер окна консоли

; задать заголовок консоли

PUSH OFFSET STR2

; установить позицию курсора

; задать цветовык атрибуты выводимого текста

PUSH OFFSET STR1

CALL LENSTR ; в EBX длина строки

PUSH OFFSET LENS

PUSH OFFSET STR1

; ждать ввод строки

PUSH OFFSET LENS

PUSH OFFSET BUF

; вывести полученную строку

; вначале задать цветовые атрибуты выводитого текста

PUSH OFFSET LENS

PUSH OFFSET BUF

MOV ECX, 01FFFFFFFh

MOV EDI, DWORD PTR [EBP+08h]

MOV ECX, 100 ; ограничить длину строки

REPNE SCASB ; найти символ 0

SUB EDI, EBX ; длина строки, включая 0

Для работы с команданой строкой применяется АРІ функция GetCommandLineA, которая возвращает указатель на командную строку. Эта функция одинакова работает как для консольных приложений, так и для приложений GUI (Graphic Universal Interface).

Пример 2. Программа вывода параметров командной строки

.MODEL FLAT, stdcall

STD_OUTPUT_HANDLE equ -11

; прототипы внешних процедур

EXTERN GetStdHandle: NEAR

EXTERN WriteConsoleA: NEAR

EXTERN ExitProcess: NEAR

EXTERN GetCommandLineA: NEAR

; директивы компоновщику для подключения библиотек

_DATA SEGMENT DWORD PUBLIC USE32 'DATA'

BUF DB 100 dup (0)

LENS DWORD ? ; количества выведенных символов

_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'

; получить HANDLE вывода

; получить количество параметров

; вывести параметры командной строки

; получить параметр номером EDI

; получить длину параметра

PUSH OFFSET BUF

; в конце - перевод строки

MOV BYTE PTR [BUF+EBX], 13

MOV BYTE PTR [BUF+EBX+1], 10

MOV BYTE PTR [BUF+EBX+2], 0

PUSH OFFSET LENS

PUSH OFFSET BUF

MOV EDI, DWORD PTR [EBP+08H]

MOV ECX, 100 ; ограничить длину строки

REPNE SCASB ; найти символ 0

SUB EDI, EBX ; длина строки, включая 0

; определить количество параметров (->EAX)

MOV ESI, EAX ; указатель на строку

XOR ECX, ECX ; счетчик

MOV EDX, 1 ; признак

CMP BYTE PTR [ESI], 0

CMP BYTE PTR [ESI], 32

ADD ECX, EDX ; номер параметра

; EBX - указывает на буфер, куда будет помещен параметр

; в буфер помещается строка с нулем на конце

; EDI - номер параметра

MOV ESI, EAX ; указатель на строку

XOR ECX, ECX ; счетчик

MOV EDI, 1 ; признак

CMP BYTE PTR [ESI], 0

CMP BYTE PTR [ESI], 32

ADD ECX, EDX ; номер параметра

MOV AL, BYTE PTR [ESI]

MOV BYTE PTR [EBX], AL

MOV BYTE PTR [EBX], 0

Для компиляции программы используются следующие командные строки:

TASM32 /ml prog.asm

TLINK32 /ap pgog.obj

Основная литература – 5121

Контрольные вопросы.

Какие аргументы использует АРІ функция GetStdHandle?

Дайте названия цветов букв и символов используемых функцией SetConsoleTextAttribute?

Назовите параметры функции CharToOem?

Какие типы событий зарезервированы операционной системой?

Тут вы можете оставить комментарий к выбранному абзацу или сообщить об ошибке.

Чтение данных из файла можно произвести с помощью функции ReadFile():

BOOL ReadFile(HANDLE hFile, (1)

LPVOID lpBuffer, (2)

DWORD nNumberOfBytesToRead, (3)

LPDWORD lpNumberOfBytesRead, (4)

LPOVERLAPPED lpOverlapped); (5)

Для того, чтобы функция выполнилась успешно, файл из которого будет производиться чтение должен быть открыт с флагом GENERIC_READ.

– hFile – хэндл того файла, из которого будет производиться чтение.

– lpBuffer – указывает на буфер, в который будет производиться чтение данных.

– nNumberOfBytesToRead определяет число байтов, которые необходимо прочесть из файла.

– в буфер lpNumberOfBytesRead будет записано число реально прочитанных байтов.

– аргумент lpOverlapped используется только для асинхронного ввода-вывода. При синхронном вводе необходимо этому параметру передать значение NULL.

; Считать данные из файла data.txt в массив структур. (struk4.asm)

.model flat, stdcall

worker struc ;информация о сотруднике

nam db 30 dup (" ") ;фамилия, имя, отчество

position db 30 dup (" ") ;должность

age db 2 dup (" ") ;возраст

standing db 2 dup (" ") ;стаж

salary db 4 dup (" ") ;оклад в гривнах

birthdate db 8 dup (" ") ;дата рождения

worker ends ; 76 байт в строке в файле

mas_sotr worker 10 dup (<>)

filename db 'data.txt',0

Ttl db 'Massiv',0h

mes1 db 'Massiv: ',0ah,0dh

mov ebx,type worker

; CreateFileA

mov eax,offset filename

; ReadFile

mov ebx,offset mas_sotr

mov esi,(type worker)*edi ; edi - индекс элемента в массиве

lea edi, bufread

Не обещаю, что работает!

Пример программы для практики

; Программа формирует массив структур. В массиве 3 элемента. Массив вводится вручную.

; На экран выводится возраст всех сотрудников

worker struc ;информация о сотруднике

nam db 15 dup (' ') ;имя

lastnam db 15 dup (' ') ; фамилия

age db 2 dup (' ') ;возраст

buf1 db 15 dup (20h)

pole1 db 2 dup (?) ; поле для вывода возраста

N=3 ; размерность массива

mas_sotr worker N dup (<>)

mes1 db 'Vvedite 3 elementa strukturi: ','$'

mnam db 10,13,'Vvedite imya: ', '$'

mlastnam db 10,13,'Vvedite familiyou: ','$'

mage db 10,13,'Vvedite vozrast: ','$'

mes db 10,13,'Vozrast=',10,13,'$'

mov dx,offset mes1 ; mes1 = 'Vvedite 3 elementa strukturi: ','$'

mov bx, offset mas_sotr

mov ax, type worker

; Цикл cykl2 – цикл формирования массива структур в памяти.

mov dx,offset mnam

mov ah,0ah ; Функция 0ah записывает в буфер buf1, находящийся по адресу в dx

mov cl,byte ptr [si]

mov dx,offset mlastnam

mov cl,byte ptr [si]

mov dx,offset mage

mov cl,byte ptr [si]

; ----------------------------------------Метка label_1: продолжение цикла cykl2, так как он получается

; очень большим, то часть цикла вынесли за его пределы.

mov ax, type worker

mov byte ptr [di],'$'

mov dx,offset mes

; ------------------------------------------В поле pole1 записывается возраст каждого сотрудника из

; массива структур в памяти. Далее содержимое поля pole1 выводится на экран.

mov bx, type worker

lea dx,[si].age ;lea dx,[si+1E]

mov dx,offset pole1

Самостоятельно на практике:

1) Переделать программу под WIN32.

Создать и открыть новый файл

Функция DOS 5Bh — Создать и открыть новый файл.

СХ = атрибут файла

DS:DX = адрес ASCIZ-строки с полным именем файла

CF = 0 и АХ = идентификатор файла, открытого для чтения/записи в режиме совместимости, если не произошла ошибка.

CF = 1 и АХ = код ошибки (03h — путь не найден, 04h — слишком много открытых файлов, 05h — доступ запрещен, 50h — файл уже существует).

Чтение из файла или устройства

Функция DOS 3Fh — Чтение из файла или устройства

АН = 3Fh

ВХ = идентификатор файла

СХ = число байт

DS:DX = адрес буфера для приема данных

Вывод:

CF = 0 и АХ = число считанных байт, если не произошла ошибка

CF = 1 и АХ = 05h, если доступ запрещен, 06h, если неправильный идентификатор

Если при чтении из файла число фактически считанных байт в АХ меньше, чем заказанное число в СХ, то при чтении был достигнут конец файла. Каждая следующая операция чтения, так же как и записи, начинается не с начала файла, а с того байта, на котором остановилась предыдущая операция чтения/записи. Если требуется считать (или записать) произвольный участок файла, используют функцию 42h (функция lseek в С).

При работе с файлами на ассемблере единичной записью является байт. Все записи имеют номера от 0 до L-1, где L длина файла. При открытии файла указатель устанавливается на запись 0. При чтении или записи указатель автоматически передвигается на n байт (где n - число прочитанных или записанных байт).

При чтении файла (функция 3FH) в АХ помещается считанное количество байт. Поэтому следует каждый раз сравнивать АХ и СХ. Если АХ>СХ, то обычно это означает, что в процессе чтения произошел переход через конец файла (устанавливается флаг СF). При записи в файл ситуация аналогична, но в этом случае неравенство содержимого АХ и СХ будет означать, что в процессе записи произошла ошибка.

Переместить указатель чтения/записи

Функция DOS 42h — Переместить указатель чтения/записи

Ввод:

АН = 42h

ВХ = идентификатор

CX:DX = расстояние, на которое надо переместить указатель (со знаком) (4 ГБ)

AL = перемещение от:

Начала файла

Текущей позиции

Конца файла

Вывод:

CF = 0 и CX:DX = новое значение указателя (в байтах от начала файла), если не произошла ошибка

CF = 1 и АХ = 06h, если неправильный идентификатор

Указатель можно установить за реальными пределами файла: если указатель устанавливается в отрицательное число, следующая операция чтения/записи вызовет ошибку; если указатель устанавливается в положительное число, большее длины файла, следующая операция записи увеличит размер файла. Эта функция также часто используется для определения длины файла. Для этого необходимо вызвать ее с параметрами СХ = 0, DX = 0, AL = 2, и в CX:DX будет возвращена длина файла в байтах.

Используя функцию 42Н, можно переместиться к любому байту файла. Ниже дается полное описание этой функции.

ВХ описатель файла

CX:DX на сколько передвинуть

AL как передвигать

0 начало файла + CX:DX,

1 от текущей позиции файла + CX:DX,

2 от конца файла + СХ:DX

Если флаг переноса установлен, то в АХ помещен код ошибки, в противном случае AX:DX показывает новую позицию в файле.

При работе с материалом данного раздела помните, что функции чтения и записи можно использовать не только с дескрипторами заранее открытых файлов, но и с дескрипторами стандартных устройств. Эти дескрипторы имеют постоянное значение и доступны в любое время функционирования системы:

  • 0 – клавиатура;
  • 1 и 2 – экран;
  • 3 – последовательный порт СОМ1;
  • 4 – параллельный порт LPT1.

Установка текущей файловой позиции

Чтение-запись в файле производятся с текущей файловой позиции, на которую указывает файловый указатель. Функция 42h MS DOS предоставляет гибкие возможности как для начального, так и для текущего позиционирования файлового указателя для последующей операции ввода-вывода.

Выход: CF = 0 – DX:AX = значение новой позиции в байтах относительно начала файла; CF = 1 – АХ = код ошибки: 1 – неверное значение в AL; 6 – недопустимый дескриптор файла.

Методы позиционирования, заданные величиной в AL, по-разному трактуют значение в паре регистров CX:DX. Метод al = 00 трактует значение в CX:DX как абсолютное. Два других метода (al = 01 и al = 02) трактуют содержимое CX:DX как значение со знаком. Необходимо быть внимательным при выполнении операции позиционирования для избежания последующих ошибок при операции чтения-записи. Так, значение в СХ: DX, позиционирующее указатель, может указывать за пределы файла. При этом выделяются два случая:

  • значение в СХ: DX указывает на позицию перед началом файла – в этом случае последующая операция чтения-записи будет выполнена с ошибкой;
  • значение в СХ:DX указывает на позицию за концом файла – в этом случае последующая операция записи приведет к расширению файла в соответствии со значением в CX:DX.

Примеры использования функции 42h приведем при рассмотрении функций чтения-записи.

Запись в файл или устройство

DS:DX – указатель на область, из которой записываются данные. Выход: CF = 0 – АХ = число действительно записанных байтов в файл или устройство; CF = 1 – АХ = код ошибки: 5 – в доступе отказано; 6 – недопустимый дескриптор.

Если при вызове функции 40h регистр СХ равен нулю, то данные в файл не записываются и он усекается или расширяется до текущей позиции файлового указателя. Если СХ не равен нулю, то данные в файл записываются начиная с текущей позиции файлового указателя. Операция записи также продвигает файловый указатель на число действительно записанных байтов.

Положение файлового указателя можно изменять явно с помощью функции 42h. Вначале приведем пример программы, выводящей данные на экран.

Эта статья лишь небольшой пример того, как можно работать с файлами, используя функции DOS. Я не буду описывать все возможные значения параметров и вдаваться в подробности. Это вы можете найти самостоятельно в справочнике.

Создание нового файла

Прежде, чем что-то записывать, необходимо создать файл. Для этого используется функция DOS 3Ch.


Запись данных в файл

Запись в файл выполняется функцией DOS 40h. Этой функции нужно передать в регистре BX тот самый дескриптор, который был получен при создании файла.


Если вам требуется записать много данных, можно вызывать эту функцию несколько раз.

Закрытие файла

После работы с файлом нужно его закрыть с помощью функции DOS 3Eh.


Если вы не закроете файл, то он будет закрыт системой при выходе из программы. Однако, хорошим стилем программирования является явное закрытие файла после завершения работы с ним.

Пример первый

Программа создаёт новый файл и записывает в него данные. Так как диск и директория не указаны, то файл создаётся в текущей папке. В данном примере в файл записываются 2 строки, получается текстовый файл. Можно работать с двоичными файлами, записывая любые байты, слова и т.д.

В результате работы программы создаётся файл, который можно открыть блокнотом:


Открытие существующего файла

Для открытия файла используется функция DOS 3Dh. В отличие от создания файла, эта функция завершится ошибкой, если файл не существует.


Чтение данных из файла

Чтение из файла выполняется функцией DOS 3Fh.


Размер буфера для данных должен быть больше или равен количеству считываемых байтов. Обратите внимание, что в AX функция возвращает количество реально прочитанных байтов. Это количество может быть меньше требуемого, например, если файл слишком короткий.

Пример второй

Читайте также: