Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Zemskov_my_sppo1

.pdf
Скачиваний:
30
Добавлен:
18.04.2015
Размер:
595.32 Кб
Скачать

Ю. В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.

ся 1, если неверен номер функции, и 6 — если указан неверный номер файла.

Теперь программа готова для чтения файла. Hадо поместить номер файла в BX, а требуемое число байтов в CX и выполнить прерывание. При возврате AX будет содержать число реально прочитанных байтов. Если AX равен нулю, то достигнут конец файла. При других ошибках устанавливается флаг переноса, а AX содержит 5 — при ошибке оборудования и 6 — если указан неверный номер файла. В следующем примере в буфер памяти считывается весь небольшой файл. Для удобства буфер располагается в сегменте данных, что существенно увеличивает размер программы на диске.

PATH DB ’A:NAME.EXT’, 0 ; строка пути к файлу

DATA_BUF DB 1000 DUP (?) ; буфер данных

HANDLE DW ? ; дескриптор файла

FILESIZE DW ? ; размер файла

; —открываем файл

LEA DX,PATH ; DS:DX указывают на путь MOV AL,0 ; для чтения

MOV AH,3DH ; функция открытия файла INT 21H ; открываем файл

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

MOV HANDLE,AX ; запоминаем дескриптор файла ; —устанавливаем файловый указатель на конец

файла:

MOV AH,42H ; функция установки указателя MOV AL,2 ; код для конца файла

MOV BX,HANDLE ; номер файла

MOV CX,0 ; смещение равно нулю

MOV DX,0

INT 21H ; устанавливаем указатель

JC POINTER_ERR1 ; обработка ошибки

MOV FILESIZE,AX ; запоминаем размер (меньше 64K)

; —возвращаем указатель на начало: MOV AH,42H ; номер функции MOV AL,0 ; код для начала файла MOV CX,0 ; смещение равно нулю

MOV DX,0

INT 21H ; устанавливаем указатель

JC POINTER_ERR2 ; обработка ошибки

; —читаем весь файл:

MOV AH,3FH ; номер функции чтения файла MOV BX,HANDLE ; дескриптор файла

MOV CX,FILESIZE ; число считываемых байтов LEA DX,DATA_BUF ; DS:DX указывают на буфер INT 21H ; читаем файл

JC READ_ERR ; обработка ошибки ; —позднее, закрываем файл:

MOV BX,HANDLE ; дескриптор файла MOV AH,3EH ; функция закрытия файла INT 21H ; закрываем файл

JC CLOSE_ERR ; обработка ошибки

3. Запись в файлы прямого доступа. Физически файлы прямого доступа ничем не отличаются от последовательных файлов, они отличаются только режимом доступа. Файл прямого доступа предполагает, что его данные организованы в виде записей фиксированной длины, таким образом положение каждой записи может быть вычислено (в после-

довательных файлах n-ный элемент ищется путем подсчета разделителей между элементами, начиная с начала файла). Операционная система автоматически выполняет эти вычисления. Однако любая программа может выполнять эту работу сама, устанавливая файловый указатель на нужную позицию и считывая последовательно такое число байтов, которое образует запись.

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

вCX:DX (CX будет содержать старший байт значения). Затем поместите в AL кодовый номер от 0 до 2. При AL = 0, указатель будет установлен со смещением CX:DX байтов относительно начала файла; при AL = 1, указатель будет установлен со смещением CX:DX относительно текущей позиции, а при AL = 2, указатель будет установлен со смещением CX:DX относительно конца файла (т.е. таким образом файл будет расширен). Отрицательные числа недопустимы

вкачестве смещений. При возврате DX:AX будут содержать новое положение указателя (старший байт

вDX). Если устанавливается флаг переноса, то произошла ошибка. В этом случае AX будет содержать 1, если указан неверный код в AL и 6 — если указан неверный номер файла.

После позиционирования файлового указателя запись прямого доступа записывается с помощью той же функции 40H прерывания 21H, которая использовалась для записи в последовательный файл. При входе BX содержит номер файла, а CX — число байтов, которое надо записать. При возврате AX будет содержать число реально записанных байтов. Если оно отличается от числа помещенного в CX, то вероятно диск полон. Kак обычно, при возникновении ошибки устанавливается флаг переноса. В этом случае AX будет содержать 5 при ошибке накопителя и 6 — если указан неверный номер файла. Пример:

HANDLE DW ? ; дескриптор файла

FILEPATH DB ’A:NEWDATA’,0 ; строка пути к файлу

REC_BUF DB 30 DUP (?) ; буфер выводимых

записей ; —открываем файл:

MOV AH,3DH ; номер функции MOV AL,1 ; открываем для записи

LEA DX,FILEPATH ; DS:DX указывают на путь INT 21H ; открываем файл

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

MOV HANDLE,AX ; сохраняем дескриптор файла ; —вычисляем позицию записи и устанавливаем

файловый указатель:

MOV AX,30 ; размер записи 30 байтов MOV CX,54 ; 54-я запись (считая с 0)

MUL CX ; теперь смещение для неё в DX:AX MOV CX,DX ; старшее слово

73

Ю. В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.

MOV DX,AX ; младшее слово

MOV AL,0 ; устанавливаем указатель на начало MOV AH,42H ; функция установки указателя

MOV BX,HANDLE ; номер файла

INT 21H ; устанавливаем указатель

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

;—пишем запись (прямой доступ): MOV AH,40H ; номер функции

MOV BX,HANDLE ; номер файла

MOV CX,30 ; размер записи

LEA DX,REC_BUF ; DS:DX указывают на буфер

INT 21H ; пишем

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

4.Чтение из файлов прямого доступа. Чтение файлов прямого доступа является обратным процессом по отношению к их записи. MS DOS вычисляет позицию в файле на диске, затем считывает запись и помещает ее в память. Затем программа должна разделить запись на поля в точности того же размера, который был использован при конструировании записи. Hе забудьте удалить символы пробела, добавленные при заполнении полей. Обсуждение записи данных в файлы прямого доступа содержит информацию, которая поможет Вам лучше понять информацию данного раздела.

В предыдущем разделе показано, как писать записи прямого доступа с помощью метода дескриптора файлов. Процедура чтения из файла с прямым доступом подготавливается совершенно аналогичным образом, путем вычисления смещения в файле, на которое должен указывать файловый указатель. DS:DX должны указывать на буфер, в который будет помещена запись, после чего надо выполнить функцию 3FH прерывания 21H. При входе CX должен содержать размер записи, а BX — номер файла.

HANDLE DB ?

FILEPATH DB ’A:OLDDATA’,0 REC_BUF DB 30 DUP(?)

;—открываем файл:

MOV AH,3DH ; номер функции MOV AL,0 ; для чтения

LEA DX,FILEPATH ; DS:DX указывают на путь к файлу

INT 21H ; открываем файл

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

MOV HANDLE,AX ; запоминаем номер файла

; —вычисляем позицию записи и устанавливаем файловый указатель:

MOV AX,30 ; размер записи

MOV CX,54 ; читаем запись 54 (считая с 0) MUL CX ; смещение записи в DX:AX

MOV CX,DX ; старшее слово смещения MOV DX,AX ; младшее слово смещения

MOV AL,0 ; устанавливаем указатель на начало файла

MOV AH,42H ; функция установки указателя

MOV BX,HANDLE ; номер файла

INT 21H ; устанавливаем указатель JC POINTER_ERR ; обработка ошибки ; —читаем запись с прямым доступом MOV AH,3FH ; номер функции

MOV BX,HANDLE

MOV CX,30 ; размер записи

LEA DX,REC_BUF ; DS:DX указывают на буфер для записи

INT 21H ; читаем запись

JC READ_ERR ; обработка ошибки ; —позднее, закрываем файл

MOV BX,HANDLE

MOV AH,3EH ; функция закрытия файла INT 21H ; закрываем файл

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

9.2. Определение дисковых ошибок и восстановление после них

Дисковые операции настолько сложны, что имеется большое количество возможных ошибок. Большинство дисковых ошибок обсуждаются вместе с операциями, при которых они могут происходить. В данном разделе они собраны вместе, чтобы помочь Вам при разработке процедуры общего назначения для восстановления после дисковых ошибок.

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

Kаждая из функций обращения к диску MS DOS использует только некоторые из возможных кодов ошибок, а некоторые функции не сообщают об ошибке. Однако во всех случаях при возникновении ошибки устанавливается флаг переноса. Если произошла ошибка, то номер кода этой ошибки возвращается в AX. Вот коды, относящиеся к дисковым операциям:

1 Hеверный номер функции

2 Файл не найден

3 Путь не найден

4 Уже открыто максимально допустимое число файлов

5 Отрицание доступа (ошибка оборудования)

6 Hеверный номер файла

15 Указан неверный накопитель

16 Попытка удалить текущий каталог

17 Hе то же устройство

18 Больше нет файлов (при поиске в каталоге с использованием шаблонов).

Восстановление после этих "мягких"ошибок несложно. Hекоторые предупреждают Вас о программных ошибках. Другие возникают из-за ошибочных действий пользователя. Если же не отвечает сам накопитель, то произошла критическая ошибка.

Начиная с версии 3.0 в MS-DOS введены расширенные коды ошибок. Они могут быть получены с помощью функции 59H прерывания 21H, когда флаг

74

Ю. В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.

переноса индицирует возникновение ошибки.

9.3.Порядок выполнения работы

1.Получить номер варианта и ознакомится с заданием.

2.Написать программу на языке ассемблера, решающую поставленную в задании задачу.

3.Оттранслировать исходный текст программы

висполняемый модуль, устранив при необходимости ошибки в исходном тексте.

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

5.Если в результате тестирования выяснится, что программа работает некорректно, откорректировать исходный текст программы и повторить шаги два предыдущих шага. Для поиска ошибок в алгоритме работы программы использовать отладчик.

6.Отлаженную программу показать преподава-

телю.

12.Даны символьные файлы F1 и F2. Определить, совпадают ли они между собой.

13.Дан файл F,компоненты которого являются целыми числами. Получить файл G,переписав в него компоненты файла F и упорядочив их по возрастанию.

14.Даны символьные файлы F1 и F2. Записать в файл G совпадающие компоненты этих файлов.

15.Дан файл F,компоненты которого являются целыми числами. Получить файл G,переписав в него компоненты файла F и упорядочив их по убыванию.

16.Дан символьный файл F. Переписать в файл G все символы, которым предшествует символ z.

17.Даны файлы F и G,компоненты которых являются целыми числами. Переписать в файл J только те компоненты, которые есть и в том и в другом файле.

18.Дан символьный файл F. Удалить из файла все пробелы и однобуквенные слова.

19.Дан текстовой файл F. Получить в файле G все строки файла F, длиной более 40 символов.

9.4.Варианты заданий

1.Даны символьные файлы F1 и F2. Переписать F1 в F2 и F2 в F1 используя вспомогательный файл.

2.Дан файл,компоненты которого являются целыми числами. Найти сумму,произведение и сумму квадратов компонент файла.

3.Дан символьный файл F. Переписать содержимое файла F в файл G, заменяя все заглавные буквы маленькими.

4.Дан символьный файл F. Переписать содержимое файла F в файл G в обратном порядке.

5.Дан файл,компоненты которого являются целыми числами. Найти число четных чисел в файле. Результат записать в файл.

6.Даны символьные файлы F1 и F2. Объединить оба файла в файл G.

7.Дан файл,компоненты которого являются целыми числами. Получить в файле G все нечетные компоненты, а в файле J все четные компоненты исходного файла.

8.Дан символьный файл F. Подсчитать, сколько раз в нем встречается комбинация символов fta.

9.Дан файл F,компоненты которого являются целыми числами. Переписать содержимое файла F в файл G в обратном порядке.

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

11. Дан символьный файл F. Подсчитать, сколько раз в нем встречается каждый из символов y, U, s, R. Результат записать в файл G.

20.Дан файл F, содержащий одинаковое количество положительных и отрицательных целых чисел. Сформировать файл G так, чтобы положительные

иотрицательные числа чередовались.

21.Дан текстовой файл F. Получить в файле G самую длинную строку файла F ( или все, если их несколько).

22.Дан файл F, содержащий одинаковое количество положительных и отрицательных целых чисел. Сформировать файл G так, чтобы посначала шли все отрицательные числа, а потом положительные.

23.Дан файл F,компоненты которого являются целыми числами. Сосчитать количество положительных, отрицательных и нулевых элементов файла. Результаты записать в файл.

24.Дан текстовой файл F. Переписать в файл G все строки файла F в обратном порядке.

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

26.Дан текстовой файл F. Переписать в файл G все строки файла F вставляя в начало каждой строки по 5 пробелов.

27.Дан текстовой файл F. Сократить число пробелов между словами, в начале и конце строк до одного.

28.Дан файл F,компоненты которого являются целыми числами. Сформировать файл G, каждый элемент которого является разностью двух соседних элементов файла F.

29.Даны 2 текстовых файла. Записать в третий файл все совпадающие строки первых двух файлов.

75

Ю.В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.

10.Организация ввода-вывода

10.1. Основные определения

Приведём классификацию внешних устройств по функциональному признаку:

1) устройства внешней памяти:

а) с произвольным (прямым) доступом (магнитные диски, в том числе «винчестеры» и дискеты; оптические и мангитооптические диски) — Direct Access Storage Device (DASD);

б) с последовательным доступом (стриммеры и

др.)

2)позиционные устройства ввода (мышь, планшеты-дигитайзеры, световое перо);

3)устройства алфавитно-цифрового вводавывода (принтер, телетайп, текстовый терминал);

4)устройства графического ввода (сканеры, видеодекодеры) и вывода (графические дисплеи, плоттеры, графические принтеры, видеокодеры);

5)сетевые и телекоммуникационные устрой-

ства;

6)устройства звукового ввода-вывода;

7)сенсорные (гироскоп или трубка Пито бортового компьютера; терморезистор системы управления температурой и др.) и исполнительные (шаговые электродвигатели, топливные насосы, нагревательные элементы и др.) устройства управляющих систем.

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

Каждый регистр имеет свой адрес. Два основные подхода к адресации регистров внешних устройств:

1)отдельное адресное пространство вводавывода: для обращения к внешним устройствам используются специальные команды, например, in и out; шина управления в этом случае содержит специальные линии, активность которых указывает на то, что на шине адреса в данный момент выставлен адрес внешнего устройства, а не ячейки памяти;

2)отображаемый в память ввод-вывод (memorymapped input/output): память и внешние устройства располагаются в общем адресном пространстве, для обращения к внешним устройствам используется те же команды, что и для обращения к памяти, например, команда mov.

При выделении адресов различным устройствам используются два подхода:

а) фиксированная адресация: одному и тому же устройству всегда выделяется один и тот же адрес (или несколько адресов, если оно имеет несколько регистров);

б) географическая адресация: каждому разъёму шины соответствует свой диапазон адресов и при подключении того же устройства к другому разъёму ему назначается другой адрес.

При первом подходе между различными устройствами возможны конфликты адресов. Современные шины (например, PCI) обычно используют второй вариант.

Современные периферийные устройства обычно имеют специальные конфигурационные регистры, с помощью которых ОС может получить различную информацию о них (название фирмы-изготовителя, модель, версия и др.), в результате становится возможной автоматическая конфигурация данных устройств при старте ОС (механизм Plug and Play, PnP).

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

1.Синхронный обмен: момент выдачи на шину данных новой информации фиксируется (стробируется) специальным сигналом шины управления (или используется самосинхронизирующийся код). Большинство синхронных протоколов асимметричны, т.е.

вкаждом цикле обмена участвует один задатчик (ведущее устройство) и один исполнитель.

2.Асинхронный обмен: передающее устройство посылает условный сигнал (стартовый символ или последовательность) и далее выставляет на своих выводах данные, меняя их во времени с фиксированным интервалом. При этом существует опасность, что часы передатчика и приёмника могут рассинхронизироваться. Передача обычно происходит последовательностями фиксированной длины (кадрами или фреймами), которые заканчиваются специальными стоповыми символами; не получив этих символов, приёмник понимает, что произошла рассинхронизация. Обычно скорость передачи по асинхронному протоколу не превышает нескольких килобод. Существует специальная разновидность асинхронных протоколов, в которых используются специальные методы повышения стабильности тактовых генераторов передатчика и приёмника (изохронный обмен).

По направлению передачи различают следующие типы устройств ввода-вывода:

1) симплексные (simplex) — осуществляющие передачу только в одном направлении;

2) полудуплексные (half-duplex) — осуществляющие передачу в обоих направлениях, но не одновременно;

3) полнодуплексные (full-duplex) — осуществляющие передачу в обоих направлениях одновременно (обычно по разным проводам).

76

Ю. В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.

По количеству бит, передаваемых одновременно, различают:

а) последовательные порты ввода-вывода (побитная передача);

б) паралллеьыне порты ввода-вывода (передача происходит байтами или многобайтными словами).

Чаще всего последовательные порты являются асинхронными, а параллельные — синхронными (имея восемь линий, неразумно экономить на девятой).

10.1.1. Параллельный интерфейс

Параллельному порту соответствуют три смежных адреса: адрес регистра данных (DR); регистра состояния (SR); регистра управления (CR). В области данных BIOS IBM PC находится таблица базовых адресов портов. Она начинается с ячейки 408H, таким образом, адрес порта LPT1 хранится в ячейке с адресом 0:408H, LPT2 — 0:40AH, LPT3 — 0:40CH, LPT4 — 0:40EH. Если порт не установлен, то в соответствующей ячейке хранится нулевое значение.

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

out reg1, reg2

где reg1 и reg2 — регистры, в которых хранится адрес порта и выводимый байт соответственно; при программировании на языке Си используют функцию

outportb (addr, data)

Регистры состояния и управления имеют особенность: некоторые их биты являются инверсными, т.е. при записи в регистр управления нулевых битов в них на самом деле записывается единица (и наоборот). То же самое происходит и при чтении из регистра состояния. На рис. 10.1 показано соответствие между сигналами интерфейса и разрядами регистров управления и состояния. В табл. 10.1 описано назначение сигналов параллельного интерфейса.

Бит 4 регистра состояния хранит «1», если прерывания (IRQ7 для LPT1 или IRQ5 для LPT2) от принтера разрешены. В этом случае прерывания вы-

рабатываются при ACK = #.

В настоящее время существует несколько модификаций параллельного интерфейса, обеспечивающие большие´ скорости обмена, чем стандартный LPT-порт. Первое же добавление, введённое с появлением IBM PS/2 — двунаправленность (type 1 parallel port). В качестве указателя направления передачи используется бит 5 регистра CR («0» — ввод, «1» — вывод). Следующая модификация (type 3 DMA parallel port) позволила использовать канал DMA для передачи данных без участия процессора. Затем появились высокоскоростные интерфейсы EPP (Enhanced Parallel Port) и ECP (Extended Capabilities Port), последний позволяет вести двусторонний обмен со скоростями до 4 Мбайт/с. В настоящее время обе эти модификации объединены в одном стандарте IEEE 1284.

Для чтения базового адреса параллельного порта LPT1 (т. е. адреса регистра данных) можно использовать следующий фрагмент на Си:

b = (int*) MK_FP (0,

0x408)

IF (*b != 0) // если

порт установлен

BASE = *b; // считаем его адрес

ELSE // иначе

......

Запись в регистр управления:

outportb (BASE+2, data 0x0B);

здесь операция «исключающее или» может использоваться, если необходимо установить правильные значения инверсных разрядов регистра.

Чтение из регистра состояния:

inportb ( BASE+1 ) >>3 ) 0x10;

здесь операция «исключающее или», как и прежде, учитывает инверсность некоторых разрядов, а сдвиг вправо позволяет избавиться от незначащих нулей в младших разрядах регистра состояния.

Наконец, для записи информации (например, вывода символа на принтер) необходимо обратиться к регистру данных:

outportb (BASE, data);

После окончания работы с параллельным портом желательно для сброса контроллера вызвать функцию 1 прерывания 17H:

mov dx,0 // 0 - для LPT1; 1 - для LPT2 mov dh, 1 // номер функции инициализа-

ции порта

int 17H // вызов прерывания DOS

77

Ю. В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.

SR

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

CR

 

 

 

 

 

 

 

 

 

 

 

 

 

7

 

6

5

4

3

2

1

0

7

6

5

4

3

 

2

 

1

 

0

 

BASE+1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BASE+2

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

-BUSY

 

 

 

 

 

 

 

 

0

0 0

0

0

0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

PE

 

 

 

 

 

-INIT

 

 

-STROBE

 

 

 

 

-ACK

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

-SLCT IN

 

 

 

 

 

 

 

 

 

 

 

 

-ERROR

 

 

 

 

 

 

 

 

 

 

 

а

 

 

 

 

 

 

 

б

 

 

 

 

 

 

 

-AUTO FD

 

 

 

 

SLCT

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис. 10.1. Регистр состояния (а) и управления (б) стандартного параллельного порта (звёздочками отмечены инверсные биты; бит 4 порта управления используется для разрешения прерываний от принтера)

Таблица 10.1. Сигналы параллельного интерфейса

Контакт

Направ-

 

Контакт

ление

 

разъёма

ПЭВМ –

Описание

разъёма

ПЭВМ

принтер

 

принтера

 

 

 

 

 

 

 

 

1

!

ST ROBE — сигнал стробирования данных (данные действи-

1/(19)

 

тельны при низком уровне сигнала)

 

 

 

 

2/(20)

 

!

D0::D7 — восьмиразрядная шина данных

. . .

2..9

9/(27)

 

 

ACK — сигнал подтверждения (acknowledge) принятия данных

 

10

 

и готовности приёмника (принтера) принять следующие данные.

10/(28)

 

Этот вход соединён с шиной +5 В через резистор и имеет в обыч-

 

 

 

 

 

ном состоянии высокий уровень

 

 

 

 

 

 

 

BUSY — сигнал занятости принтера обработкой полученных дан-

 

11

 

ных и неготовности принять следующие данные. Этот сигнал ак-

11/(29)

 

тивен также при переходе принтера в режим off-line или при от-

 

 

 

 

 

сутствии бумаги, или если буфер принтера заполнен

 

12

 

P E — сигнал конца бумаги (Paper End)

12/(30)

 

 

 

 

13

 

SLCT — сигнал готовности приёмника (принтера) принимать дан-

13

 

ные (select). У многих принтеров всё время SLCT = 1

 

 

 

14

!

AUT O F D — сигнал автоматического перевода строки. Получив

14

 

его, принтер переводит каретку на новую строку (auto feed).

 

 

 

ERROR — сигнал ошибки принтера (активен при внутренней

 

15

 

ошибке принтера, переходе в режим off-line или при отсутствии

32

 

 

бумаги)

 

 

 

 

 

16

!

INIT — сигнал инициализации (сброса) принтера (длитель-

31/(16)

 

ность не менее 2;5 мкс). Происходит очистка буфера печати

 

17

!

SLCT IN — сигнал принтеру о том, что он выбран и последует

36

 

передача данных (select in)

 

 

 

 

16, 17,

18..25

GND — земля (ground)

19..30, 33

78

Var
BufferHead : word absolute 0 :41A; BufferTail : word absolute 0 :41C; BufferKeyb : array[0..15] of Word absolute 0 :41E;
Буфер обслуживается стандартным обработчиком прерывания от клавиатуры (int 09H). Когда буфер переполняется, выдаётся звуковой сигнал. Для очистки буфера надо выполнить присваивание
BufferTail := BufferHead (или наоборот). Каждому нажатию на клавиатуру соответствует
двухбайтовый код. При нажатии на функциональные клавиши, клавиши управления курсором, клавиатурные комбинации с “Alt” первый байт кода всегда нулевой.
Кроме этого, можно обращаться напрямую к порту клавиатуры, его адрес 60H. Но в этом случае коды нажатых клавиш другие и могут даже отличаться на различных клавиатурах.
Чтобы узнать коды различных клавиш, можно использовать программу, приведённую в листинге 11.3.
Для распознавания нажатия на клавиши Shift, Ctrl, Alt и других можно использовать регистр флагов клавиатуры:
OldIntProcAddr : Pointer );
где IntNo — номер прерывания, IntProc — адрес новой программы для его обработки.
Для того, чтобы узнать адрес существующего обработчика используется процедура
Procedure GetIntVec( IntNo : Byte; Var
: Pointer);

Ю.В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.

11.Работа с прерываниями

11.0.2.Создание обработчика прерываний

всистеме Turbo Pascal

Процедура обработки прерывания в Turbo Pascal должна выглядеть следующим образом:

{$F+}

Procedure IntXX(Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP : Word); INTERRUPT;

begin

...

end;

{$F-}

Имя процедуры может быть любым. Имена параметров соответствуют регистрам микропроцессора и должны задаваться в указанном порядке. Внутри процедуры обработки прерывания не должны вызываться какие-либо паскалевские процедуры вводавывода или динамического распределения памяти, т. к. они нереентерабельны.

Для установки нового вектора прерывания предназначена процедура

полнения необходимых действий (или перед ними) должна вызвать старую процедуру обработки (ведь её адрес известен в результате выполнения GetIntVec). Для вызова старого обработчика в начале или в конце новой процедуры обработки прерывания необходимо написать следующий фрагмент на ассемблере:

asm

pushf ; сохранили флаги call OldIntProcAddr

end;

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

Exec("имя_программы", "командная строка

с параметрами")

Если во время обработки прерывания требуется запретить другие прерывания, то необходимо определить inline-процедуру

Procedure CLI; inline($fa);

Procedure SetIntVec(IntNo : Byte; IntProc Для разрешения прерываний используется процедура

Procedure STI; inline($fb);

Если обработчик прерывания должен реагировать на нажатия клавиш, то рекомендуется использовать системный буфер клавиатуры, расположенный в области данных BIOS по адресам с 0:041EH по

0:043DH включительно. Коды всех нажатых клавиш этот адрес возвращается в OldIntProcAddr. накапливаются в этом кольцевом буфере. На теку- Структура программы с процедурой обработки щее начало буфера ссылается указатель, хранящийпрерывания показана в листинге 11.1. Здесь во время ся по адресу 0:41AH, а на конец — указатель по

работы программы нужное прерывание обрабатыва- адресу 0:41CH: ется процедурой IntXX, а перед завершением про-

граммы восстанавливается старый обработчик. Часто требуется, чтобы наш новый обработчик

прерывания остался в системе после завершения нашей программы. Для этого можно использовать процедуру Keep (завершиться, но остаться резидентным).

Для примера в листинге 11.2 приведена программа, которая перехватывает прерывания от таймера (они происходят каждые 55 миллисекунд) и выводит время (часы, минуты, секунды) в правый верхний угол экрана. Данная программа работает также в Windows (разумеется, в окне DOS). Обратите внимание на директиву компилятору {$M} в самом начале, без неё при запуске программа запросила бы всю доступную область памяти под хип и, оставшись резидентной в памяти, заблокировала бы всю дальнейшую работу (разумеется, в Windows работа была бы заблокирована только в окне DOS, а не во всей системе, хотя, при отладке своего варианта задания вы скорее всего будете наблюдать обратное).

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

79

Ю. В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.

KeybFlag : word absolute $0:$417;

торые специальные комбинации клавиш заранее

В этом регистре младший (нулевой) бит младше-

определёнными цепочками символов (макроопреде-

го ($0:$417) байта соответствует правой клави-

ление).

ше Shift, следующий (первый) — левой клавише

6. Написать обработчик прерывания, ко-

Shift, второй — клавише Ctrl, третий — Alt.

торый при нажатии на комбинацию клавиш

Эти биты установлены, если клавиша находится в

“Ctrl+PrintScreen” играет короткую мелодию.

нажатом состоянии, и сброшены в противном слу-

7. Написать обработчик прерывания, который

чае. Четвёртый бит установлен, если включен ре-

при нажатии на комбинацию клавиш “Ctrl+Alt+Del”

жим ScrollLock, пятый — NumLock, шестой —

гасит экран, выводит изображение черепа со скре-

CapsLock, седьмой (старший) бит — InsLock.

щенными костями и только при повторном нажатии

Что касается старшего байта ($0:$418), то тре-

на “Ctrl+Alt+Del” перезагружает компьютер.

тий его бит устанавливается, если включен режим

8. Написать обработчик прерывания «тест мы-

Ctrl+NumLock, четвёртый — если нажата клавиша

ши», который во время работы любой программы при

ScrollLock, пятый — если нажата NumLock, ше-

стой — CapsLock, седьмой — если нажата Insert,

каждом движении мыши выводит на экран её новые

остальные биты не используются и всегда равны ну-

координаты, а при каждом щелчке на кнопку мы-

лю.

ши — зажигает на мгновение цветной прямоуголь-

ник.

Например, определить, что в данный момент на-

жата клавиша Alt, можно следующим способом:

9. Написать обработчик прерывания «дезориен-

if (Mem[$0:$417] and $08)<>0 then ...

тация мыши», который во время работы любой про-

(здесь 8 — это 23 , т. к. клавише Alt соответствует

граммы при каждом движении мыши заставляет её

третий бит регистра флагов).

указатель на экране двигаться в потивоположную

сторону.

Комбинация клавиш Ctrl+Break обычно приво-

дит к окончанию работы программы DOS. Прерыва-

10. Написать обработчик прерывания «мышь для

ние, которое генерируется при нажатии этой комби-

левши», который во время работы любой программы

нации клавиш, имеет номер 1BH. Если его перехва-

заменяет щелчки правой кнопки мыши — левыми и

тить, то вместо окончания работы программы (или

наоборот.

перед ним) можно выполнить какие-либо действия.

11. Написать обработчик прерывания «деление

11.1.Варианты заданий на разработку

на 0», который при попытке деления на 0 из любой

программы выдаёт на экран соответствующее сооб-

обработчика прерываний в системе DOS

щение и просит ввести результат, после чего возвра-

 

1. Создать «цепочку» из нескольких однотип-

щет управление в прерванную программу вместе с

ных обработчиков прерывания от таймера, каждый

введённым результатом.

из которых выводит текущее время в своей позиции

12. Написать обработчик прерывания, который

на экране и своим цветом, после чего вызывает дру-

при попытке создать на дискете новый каталог со-

гого. Сможете ли вы сделать так, чтобы программа

здаёт каталог с именем, символы которого идут в

«умела» устанавливать новые копии обработчика и

обратном порядке.

снимать старые?

13. Написать обработчик прерывания, который

2. Написать обработчик прерывания от клави-

при попытке удалить с дискеты каталог вместо уда-

атуры, который при нажатии определённой комби-

ления переименовывает его в DelXXX, где XXX

нации клавиш (например, “Ctrl+Alt+T”) выводит на

наименьший номер среди возможных для текущего

экран сообщение (например, текущее время), а при

каталога (чтобы имена не совпадали).

нажатии другой комбинации — удаляется это сооб-

14. Написать обработчик прерывания, который

щение с экрана, восстанавливая его старое содержи-

при открытии любого файла с дискеты открывает

мое.

на самом деле один и тот-же заранее обусловленный

3. Написать обработчик прерывания, блокирую-

файл, так что все последующие операции (в том чис-

щий запись информации на дискету, который при

ле и закрытие) производятся с подменённым файлом.

попытке записи на дискету из любой программы на

15. Написать обработчик прерывания, который

самом деле ничего не делает, но сообщает, что за-

при нажатии Ctrl+Break запускает копию выпол-

пись произведена без ошибок.

няемой программы, после чего передаёт управление

4. Написать обработчик прерывания от клавиа-

туры, который при работе любой программы, обра-

старому обработчику, в результате чего программа

щающейся к буферу клавиатуры, подменяет каждую

прерывает своё выполнение, но вместо неё запуска-

действительно нажатую клавишу её «соседом» слева

ется новая копия.

или справа (по расположению на клавиатуре).

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

5. Написать обработчик прерывания от клави-

 

атуры, который при работе любой программы, об-

1. Какие программы MS-DOS называются рези-

ращающейся к буферу клавиатуры, подменяет неко-

дентными?

80

Ю. В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.

2. Как организована работа с прерываниями в

3.

Какие операции необходимо

MS-DOS?

4.

 

Листинг 11.1. Структура программы с обработкой прерывания в системе Turbo Pascal

Var

OldIntXX : Pointer;

{Здесь сохраняется адрес старого обработчика}

..........................

Procedure IntXX(.....

); interrupt;

..........................

end; {IntXX}

 

Begin

GetIntVec(XX, OldIntXX); {Запомнили старый вектор} SetIntVec(XX, @IntXX); {Установили новый вектор}

..........................

{теперь прерывание XX обрабатывается процедурой IntXX}

..........................

SetIntVec(XX, OldIntXX); {Вернули старый вектор} End.

81

Ю. В. Земсков. Системное и прикладное программное обеспечение. Конспект лекций, варианты заданий и методические указания в лабораторным работам. ВГИ ВолГУ, 2002 г.

Листинг 11.2. Пример программы в системе Turbo Pascal, использующей обработку прерывания по таймеру

{$M 1024, 0, 0} {Ограничили область стека 1024 байтами; мин. и макс. длина хипа - нулевые}

Program Clock; Uses DOS; Const

Segment = $B800; {Начальный адрес видеобуфера}

Col = 73; {Будем выводить время, начиная с 73 позиции} Row = 1; { верхней строки.} Attr = #$41; {Синие буквы (1) на красном фоне (4)}

Var

min, sec, msec, hour, Offset, p : Word;

Procedure Int1C; interrupt; var

time : string[8]; CurStr : string[2];

OutTime : array[1..16] of char; {8 символов и 8 атрибутов} begin

Inc(msec, 55); {Прерывание происходит каждые 55 мс} if msec < 999 then Exit; {секунды ещё не изменились}

Dec(msec,1000);

Inc(sec); p := 0;

if sec > 59 then begin

 

Dec(sec, 60);

p :=

1;

end;

 

 

Inc(min, p);

p := 0;

if min > 59 then begin

 

Dec(min, 60);

p :=

1;

end;

 

 

Inc(hour, p);

 

 

if hour > 23 then hour

:= 0;

Str(hour:2, time); {Перевести число в строку}

Str(min:2, CurStr);

time := time + ’:’ + CurStr;

Str(sec:2, CurStr);

time := time + ’:’ + CurStr;

for p:=1 to 8 do begin

 

if time[p]=’ ’ then time[p] := ’0’; OutTime[p shl 1 - 1] := time[p]; OutTime[p shl 1] := Attr;

end;

Move(OutTime, Mem[Segment:Offset], SizeOf(OutTime)); {Прямая запись в видеобуфер}

end; {Int1C}

Begin

Offset := (Row-1)*160+(Col-1) shl 1;

{Нашли смещение относительно начала видеобуфера} GetTime(hour, min, sec, msec); msec := msec*10; {Получили текущее время}

SetIntVec($1C, @Int1C); {Установили новый вектор} Keep(0); {Завершиться, но остаться резидентной} {Старый обработчик восстанавливать не будем}

End.

82

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]