Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Лекция №10. Работа с файлами. Управление файловой системой. Консольный ввод в ассемблере.




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

Чтение данных из файла можно произвести с помощью функции 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)

.386

.model flat, stdcall

extrn ExitProcess:PROC

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 байт в строке в файле

.data

mas_sotr worker 10 dup (<>)

N db 10

filename db 'data.txt',0

fname dd 0

handle dd?

bufreal dd?

mem dd?

bufread dd?

Ttl db 'Massiv',0h

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

.code

start:

mov ecx,N

mov ebx,type worker

mov mem,ebx

lea edi,mas_sotr

; CreateFileA

mov eax,offset filename

mov fname,eax

push 00000000h;

push 00000080h;

push 00000003h

push 00000000h

push 00000001h

push 0C000000h

push fname

call CreateFileA

cmp eax,0

jz exit

mov handle,eax

; ReadFile

xor eax,eax

mov ecx,10

mov esi,0

mov edi,0

cld

label_1:

push 0

push bufreal

push mem

push bufread

push handle

call ReadFile

mov eax,bufreal

cmp eax,mem

jne exit

mov ebx,offset mas_sotr

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

add edi,ebx

push ecx

mov ecx,mem

lea edi, bufread

rep movsb

pop ecx

inc edi

loop label_1

 

exit:

push 0h

call ExitProcess

end start

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


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

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

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

masm

model small

.stack 100h

 

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

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

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

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

worker ends

 

.data

buf1 db 15 dup (20h)

pole dw?

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

db 0ah,0dh,'$'

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,'$'

 

.code

assume ds:@data,es:@data

start:

mov ax,@data

mov ds,ax

xor ax,ax

push ds

pop es

Vvod:

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

mov ah,09h;Функция Dos вывода сообщения на

int 21h

mov cx,N

mov si,0

mov bx, offset mas_sotr

mov ax, type worker

mov dl,0

mul dl

add ax,bx

cld

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

cykl2:

push cx

mov di,ax

mov pole,ax

 

mov dx,offset mnam

mov ah,09h;Функция Dos вывода сообщения на

int 21h

lea dx,buf1

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

; введённую строку

int 21h

push si

lea si,buf1

add si,1

mov cl,byte ptr [si]

add si,1

rep movsb

pop si

 

mov dx,offset mlastnam

mov ah,09h;Функция Dos вывода сообщения на

int 21h

lea dx,buf1

mov ah,0ah

int 21h

push si

lea si,buf1

add si,1

mov cl,byte ptr [si]

mov di,pole

add di,15

add si,1

rep movsb

pop si

 

mov dx,offset mage

mov ah,09h;Функция Dos вывода сообщения на

int 21h

lea dx,buf1

mov ah,0ah

int 21h

push si

lea si,buf1

add si,1

mov cl,byte ptr [si]

mov di,pole

add di,30

add si,1

rep movsb

pop si

 

jmp label_1

m1:

loop cykl2

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

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

label_1:

pop cx

cmp cx,1

je vivod

inc si

mov ax, type worker

mov dx,si

mul dl

add ax,bx

jmp m1

; -------------------------------------------В конец массива структур записываем конец вывода '$'.

Vivod:

mov byte ptr [di],'$'

mov dx,offset mes

mov ah,9h

int 21h

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

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

 

lea si,mas_sotr

mov bx, type worker

mov ax,0

lea di,pole1

mov cx,3

cykl_vivod:

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

mov si,dx

movsw

mov dx,offset pole1

mov ah,09h

int 21h

lea di,pole1

loop cykl_vivod

 

mov AX,4C00h

int 21h

 

end start

 

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

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

2) Создать массив структур mas_sotr2 worker 7 dup (<>). Инициализировать массив структур в программе. На экран выдать сообщение в окне MessageBoxA. Сообщение должно содержать все данные структуры для самого старшего сотрудника.

 


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

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

Ввод:

AX = 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Н, можно переместиться к любому байту файла. Ниже дается полное описание этой функции.

АН 42Н

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

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

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

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

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

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

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


Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...