Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Лекция №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 показывает новую позицию в файле. Переместить указатель чтения/записи в Win32 DWORD SetFilePointer(HANDLE hFile, LONG IDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod);
|
||||
Последнее изменение этой страницы: 2016-09-13; просмотров: 1137; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.222.164.176 (0.009 с.) |