
- •Ижевский государственный технический университет
- •6. Оверлей 32
- •8.10. Стандартные библиотеки 52
- •Экзаменационные вопросы 52
- •1. Назначение системного программного обеспечения (спо)
- •Ос и языки программирования
- •2. Обслуживание ввода-вывода
- •2.1. Организация ввода-вывода
- •2.2 Способы управления пу Понятие драйвера пу
- •2.2.1. Синхронный ввод-вывод
- •2.2.2. Асинхронный ввод-вывод
- •2.2.3. Буферный ввод-вывод
- •3. Буферный обмен информацией в языках программирования.
- •4. Управление и доступ к оперативной памяти.
- •4.3. Управление реальной памятью
- •Разделы фиксированной длины
- •Использование разделов переменного размера
- •Использование перемещаемых разделов
- •Защита памяти
- •5. Библиотека dos
- •12. Прерывание 17h – работа с принтером
- •Функция 00h – прочитать время
- •6. Оверлей
- •6.1 Структура программного комплекса
- •6.2. Распределение памяти в оверлейной структуре
- •7. Встроенный в turbo pascal assembler
- •7.2. Режимы адресации в Ассемблере
- •7.4. Выражения для управления памятью
- •7.5.Выражения в Ассемблере
- •7.6. Команды Ассемблера
- •7.6.3. Команды ввода вывода
- •7.6.4. Адресные команды
- •7.6.7. Строковые команды
- •Test Аналогична команде and, но результат операции не записывается в 1 операнд.
- •Установить операнд:
- •8. Язык программирования с.
- •8.10. Стандартные библиотеки
- •Литература
- •Экзаменационные вопросы
- •На тему: название темы
- •Примечание: если курсовая работа выполняется двумя и более студентами, обязательно разбивка задач для каждого студента конкретно.
- •Состав пояснительной записки:
2.2.2. Асинхронный ввод-вывод
Современные процессоры являются невероятно быстрыми по сравнению с теми, которые использовались в прошлом. Они гораздо быстрее большинства ПУ. Пока устройство обрабатывает один запрос, процессор может выполнить тысячи строк кода. В идеале у приложения должна быть возможность использовать процессор, пока устройство пересылает или принимает данные. Такой способ, при котором обработка и передача информации ведутся параллельно называют асинхронным вводом-выводом.
Асинхронный ввод-вывод имеет важное преимущество перед синхронным – возможность повышения скорости работы приложений. Пока устройство занято пересылкой данных, приложение продолжает выполнять другую работу. Кто не выполнял так называемую фоновую печать документов в Word из под Windows? Но в обмен на достоинства асинхронный ввод-вывод требует большего объема программирования, а следовательно кода и занимаемой ОС памяти.
2.2.3. Буферный ввод-вывод
Т.к. скорости работы процессора и ПУ сильно различаются, то для повышения производительности вычислительной системы применяют буферизацию ввода-вывода. Для этого выделяют специальную зону в памяти – буфер для улучшения взаимодействия ПУ с программами пользователей. Отделяя работу процессора от работы периферии, надеются уменьшить время его пребывания в неактивном состоянии. Программы пользователей и ПУ передают информацию в буфер или из него. Чем больше размер буфера, тем эффективнее отделение процессора от периферии. Стремление не занимать слишком много под памяти привело к размещению буферов либо на диске (спулинг или свопинг), либо в виртуальной памяти.
Общие принципы обслуживания буферного ввода-вывода описываются следующими спецификациями:
– при обмене с ПУ используются записи фиксированного размера;
– размер буфера фиксирован и может вместить целое количество записей;
– для программы пользователя обмен с буфером имитируется ОС как обмен с ПУ, следовательно, должен сохраняться порядок передачи информации на хранение и изъятие между буфером и ПУ и ни одна запись не должна потеряться;
– бесполезное ожидание для процессора и ПУ сведено к минимуму за счет того, что устройство ввода-вывода постоянно готовы к работе.
Буферный обмен данными может быть как синхронным, так и асинхронным.
3. Буферный обмен информацией в языках программирования.
В любой операционной системе ориентированной на платформу IBM PC стандартный обмен информацией между периферийными устройствами и процессором осуществляется через использование файлов. При этом процесс обработки заключается в следующем:
1. супервизор обращается к необходимому устройству и опрашивает его готовность.
2. опрашивается состояние устройства и ищется на нем необходимый файл.
3. в куче выделяется буфер для обмена информацией (в MS-Dos и Windows величина буфера равна 512 байт).
Если ОС многозадачная, то для процесса обмена выделяется поток обмена. Необходимо помнить, что потоки обмена различаются в зависимости от условий: типа процессора, типа операционной системы. Поток обмена информацией для MS-DOS всегда один или несколько непересекающихся. Для Win9x несколько пересекающихся, но не выполняющихся одновременно. Для Windows моложе Win9х несколько пересекающихся, в том числе и выполняющиеся одновременно.
4. Распределяется внутри программы файловая переменная.
5. Происходит процесс обмена информацией по алгоритму для чтения:
Информация вводится в буфер.
Происходит процесс чтения в соответствии с форматом определенным в программе в оперативной памяти. Если данная больше 512 байт, то происходит переход указателя в буфере на необходимую позицию. Если данные больше 512 байт или данные начинаются в одном буфере и заканчиваются в другом то чтение производится в два этапа: сначала из старого буфера, далее заполнение нового и чтение остатка из него.
6. После окончания процесса обмена информацией файл закрывается, и буфер в зависимости от языка программирования может быть освобожден (в Си автоматически, в Pascal’e не автоматически).
В Config.sys пользователь должен определить количество одновременно открытых файлов: files = <n> , n=10 по умолчанию; количество буферов: buffers=<n>, n=10 по умолчанию; количество потоков, работающих одновременно: fbsd=<n>, n=1 по умолчанию (необходимо указывать только для MS-DOS или если используем приложения MS-DOS под Win9x).
Для работы Turbo Pascal достаточно стандартных установок. Для транслятора Delphi рекомендуется >20 файлов и буферов, особенно если используем работу с базами данных.
С точки зрения языков программирования существует 3 типа файлов:
-
тип файла
скорость
Текстовый
3
Типизированный
2
Нетипизированный
1
В связи с выше изложенным алгоритмом наиболее долго в программе интерпретируются текстовые файлы, средняя скорость для типизированных и максимальная для нетипизированных. В последних двух случаях программист для увеличения скорости обмена должен указывать размер типа или буфера обмена кратный 512 байт.
Таблица 1.
Файловая обработка
Задача |
Текстовый файл |
Типизированный файл |
Нетипизированный | ||||
Тип данного с которым работает файл |
Любой ординарный тип |
Любой тип |
Любой тип | ||||
Объявление в разделе переменных |
F:Text |
F:file of <type> |
F:file | ||||
Определение файла в тексте программы |
Assign(F, ”name”), AssignFile(F, ”name”) в Делфи | ||||||
Открыть файл для чтения |
Reset(F) |
Reset(F) |
Reset(F,<k>) <k>-типа word, размер минимального кол-ва информации считываемой из файла | ||||
Открыть новый файл для записи |
Rewrite(F) |
Rewrite(F) |
Rewrite(F,<k>) | ||||
Изменение файла |
Append(F) (только в конец файла) |
Reset(F) |
Reset(F,<k>) | ||||
Чтение |
Read(F,<параметр>); ReadLn(F, <параметр>). Фактическое чтение осуществление только после выполнения ReadLn. |
Read(F,<тип>); Чтение осуществляется в процессе появления оператора. |
BlockRead (F:file;var Pole; kol:word [; fact:word] ); F-файловая переменная, Pole-область памяти куда происходит считывание информации, kol-количество одновременно считываемых записей информации (общая длинна считываемой информации в байтах равна k*kol). В процессе чтения после конца файла не возникает ошибки приводящей к снятию программы, для успешной работы надо следить за процессом чтения информации. | ||||
Запись |
Write(F,<параметр>) Writeln (F,<параметр>) |
write(F,<тип>); |
BlockWrite (F, pole, kol [, fact]). | ||||
Ситуации, возникающие после чтения / записи | |||||||
Ситуация конца файла |
Eof(F:text):boolean |
Eof(F:file of <type>):boolean |
Eof(F:file):Boolean | ||||
Ситуация конца строки |
Eoln(F:text):Boolean |
Нет |
нет | ||||
Позиционирование по файлу |
Невозможно |
Seek(F:file of <type>;n:longint) |
Seek(F:file;n:longint) | ||||
Адреса записей |
Нет |
начиняя с 0 |
начиная с 0 | ||||
Закрытие файлов |
Close(F:text) |
Close(F:file of <type>) |
Close(F:file) | ||||
Действия по директивам компилятора по обработке ошибок ввода-вывода |
{$I+}-передает управление ошибками операционной системе {$I-}- передает управление ошибками программисту | ||||||
Действует на все операции |
Действует на все операции |
Действует на: Assign, Reset, Rewrite, Seek, Close. |
1) Практически в любой программе обработка текстов и типизированных файлов всегда сводится к нетипизированному файлу и BlockRead, BlockWrite замещаются макрокомандами ассемблера.
2) При создании приложений в Delphi не рекомендуется работать с обычными файлами, лучше всего подключать объекты работы с БД по различным форматам.
При этом необходимо помнить, что обработка текстовых файлов выполняется на порядок дольше.
3.1. Функции и команды по файловой обработке.
FileSize (f: file): longint – определить размер файла в байтах. Файл обязательно должен быть распределён. Действует на все типы файлов.
FilePоs (f: file): longint – определить позицию внутри файла. Файл должен быть распределён и открыт. Функция действует на типизированные и не типизированные файлы.
Rename (f: file; new. name: string); файловая строка, хранящая переменную, новое имя файла. Файл должен быть распределен, но не открыт. если на диске существует файл с новым именем, и управлением вводом выводом не передано ОС в процессе выполнения команды может произойти ошибка. Тип файла любой.
Erase (f: file)-уничтожить файл. Файл должен быть распределён, но не открыт.(!) После выполнения функций файловая переменная принимает значение “неопределенно” (const “nil”) если файла нет на носителе или атрибуты его не соответственно уничтожены (т.е. файл только для чтения) в процессе выполнения может возникнуть ошибка.
3.2. Пример обработки не типизированного файла.
Пример: Написать утилиту, копирующую один файл в другой.
При копировании проверяем следующие события: 1.Копируемого файла нет на диске; 2.На диске уже существует файл, в который мы копируем информацию. 3. Считаем: переписываем в файл до первого сбоя.
Запуск программы будем осуществлять с параметрами.
PROGRAMM MY_COPY;
Var
kol, I, N, J : integer;
ARR: array[1…512] of byte;
F, F1: file;
Begin
If ParamCaunt<2 then
begin
Writeln(“В качестве параметров должны быть заданы 2 имени файла”);
halt(1)
end.
{$I-}
Assign(f ,ParamStr[1]);
reset(f,1);
{$I+}
if IOResult <>0 then
begin
writeln(“Oшибка при открытии ”+Param Str[1]);
halt(2);
end;
{$I-}
Assign(f1 , ParamStr[2]);
reset(f1,1);
{$I+}
if IOResult<>0 then Rewrite(f1,1)
else
begin
writeln(“уже есть”+Param Str [2]);
close (f); close(f1)
halt(3);
end;
Repeat
BlockRead(f, ARR, 512, I);
Block rite(f1, ARR, I, N);
Until (I <> N) OR (I<>512);
Close(f);
Close(f1);
IF (I<> N) then
Begin
Writeln (“ Ошибка записи в” + Param Str[2]);
Halt(4);
end;
end.
Комментарий к программе:
Распределяем несколько целых переменных. Область ARR=512 байтам равна стандартному блоку ОС MSDOS, Windows 9x. Распределяем 2 файловые переменные как не типизированные файлы.
Проверяем, чтобы в программу передавалось не менее 2-х параметров. Итак, переменная ParamCount содержит количество параметров передаваемых в программу. Пред определенный массива ParamStr хранит в себе параметры передаваемые в программу. При этом начальный индекс массива=0 и в нулевом элементе массива хранится имя, выполняемого загрузочного модуля. При работе в ОС MSDOS количество параметров может быть произвольно, но общая их длина, включая разделяющие их пробелы, не должна превышать 128 символов с именем выполняемого модуля. Выдаем сообщение об ошибке и выходим с кодом завершения 1.
После этого в системной переменой ERROR LEVEL будет хранится число 1. По умолчанию при нормальном завершении программы в этой переменой хранится всегда “0”.
Проверяем существует ли на диске файл определяющий первым параметром, если его нет то выходим с кодом завершения 2.
Поверяем есть ли на диске файл определяемый 2 параметром, если в процессе выполнения программы произошла ошибка, то открываем новый файл с длиной блока равной 1. Если такой файл существовал, то выводим сообщение и выходим с кодом возврата 3.
Осуществляем цикл перезаписи. Читаем в массив ARR-512 блоков, количество прочитанных блоков помещаем в переменную I. Записываем в файл f1 из массива ARR I блоков. Результат блоков - записи заносим в переменную N. Цикл заканчивается, если количество записанных блоков не соответствует количеству прочитанных. Или количество прочитанных не соответствует 512.
В данном случае может быть 2 ошибки: ошибка чтения и конец файла. Ошибку чтения не анализируем в данной программе.
Если произошла ошибка записи, то выводим о ней сообщения. Закрываем файлы с кодом возврата 4.