Лекция №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 - 2025 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|