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

Информатика

.pdf
Скачиваний:
96
Добавлен:
11.05.2015
Размер:
1.73 Mб
Скачать

161

Примечание. В файл Disp_sec.asm необходимо добавить небольшую процедуру Write_sector.asm. Данная процедура не имеет параметров и выполняет переписку содержимого переменной Sector в область памяти, начальный адрес которой находится в переменной Address. Практическая польза от данной процедуры проявится в следующем разделе, когда будет создана реальная процедура Edit_sector.

15.РЕДАКТИРОВАНИЕ ИНФОРМАЦИИ В ОП

15.1.Алгоритм редактирования сектора

Редактирование сектора выполняет процедура Edit_sector, инициируемая диспетчером при нажатии клавиши <F4>. После того, как процедура Edit_sector запущена, она, во-первых, выполняет обработку своих команд. Такими командами являются клавиши <F4> и <Esc>, выполняющие завершение функции редактирования, а также клавиши, выполняющие управление курсором:

→ – переместить курсор на одну позицию вправо; ← – переместить курсор на одну позицию влево;

– переместить курсор на одну позицию вверх;

– переместить курсор на одну позицию вниз.

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

Алгоритм процедуры Edit_sector приведен на рис. 49. Этап «Вывод Sector» реализуется путем вызова процедуры Disp_sector. Для того чтобы выполнить этап «Инициализация курсора», обнуляются две переменные, используемые для управления внутри процедуры Edit_sector:

162

1)B (длиной 1 байт) – номер редактируемого байта в глобальной переменной Sector;

2)Nt (длиной 1 байт) – номер (0 или 1) редактируемой тетрады в байте.

Вывод Sector

Инициализация

курсора

Ожидание

нажатия

клавиши

нет Управл. клавиша

да да

<Esc>

нет

нет

Шестн. цифра

да

Шестн. цифра

Sector

Инициализация

курсора

Вывод Sector

да

<F4>

нет

Исполнение

команды

Рис. 49. Алгоритм процедуры Edit_sector

163

Далее вызывается процедура Set_cursor, выполняющая установку курсора в ту позицию экрана, которая соответствует переменным B и Nt.

Этап «Ожидание нажатия клавиши» реализуется с помощью известного нам системного вызова BIOS – “int 16h”, функция 0. Напомним, что данный вызов возвращает в регистре AL код ASCII нажатой клавиши, а в AH – скан-код клавиши. Определение управляющего символа производится по наличию у клавиши нулевого скан-кода.

Если управляющая клавиша не является клавишей <F4>, то производится исполнение соответствующей команды путем вызова процедуры Edit_command, рассматриваемой ниже. Что касается клавиши <Esc>, то она не отнесена к управляющим клавишам, так как ее ASCII-код ненулевой – 1Bh. Так как сканкод клавиши <Esc> – 01h, то для проверки нажатия клавиши <Esc> следует сравнить содержимое регистра AX с числом 011bh.

Для проверки того, что введенный символ является шестнадцатеричной цифрой, можно воспользоваться слегка переделанной процедурой ввода шестнадцатеричной цифры Read_digit_hex, разработанной ранее. Переделанная процедура должна не сама вводить символ с клавиатуры, а получать его ASCII- код в качестве входного параметра. Естественно, что следует изменить название процедуры.

Что касается записи шестнадцатеричной цифры в переменную Sector, то для этого требуется разработать новую процедуру – Write_digit_sector.

Последними двумя этапами процедуры Edit_sector являются инициализация курсора и вывод переменной Sector на экран, для реализации которых используются соответственно процедуры Set_cursor и Disp_sector. Может показаться странным выполнение инициализации курсора в конце алгоритма редактирования сектора, так как другие наши процедуры курсор не используют. Наличие данного этапа обусловлено следующим. Вспомним, что курсор указывает на ту позицию экрана, в которой будет выведен следующий символ. Поэтому вывод на экран строки символов, выполняемый процедурой Disp_sector, также начинается с позиции, отмеченной курсором. Если не

164

установить курсор в верхний левый угол изображения, то часть этого изображения не будет показана. Можете проверить это практически.

П о л у ч и т е исходный текст процедуры Edit_sector и добавьте его в файл

Disp_sec.asm.

15.2. Установка курсора

Установку курсора в требуемую позицию на экране выполняет процедура Set_cursor. Данная процедура преобразует одну пару чисел (B, Nt) в другую пару чисел ((DL), (DH)), где B – номер байта в переменной Sector, Nt – номер тетрады в байте, (DL) – координата курсора на экране по горизонтали, (DH) – координата курсора на экране по вертикали. В завершении процедура обращается к BIOS с целью установить курсор в точку экрана с заданными координатами.

Для установки курсора используется системный вызов “int 10h” (функция 2, подфункция 0). Этот системный вызов требует предварительной записи в регистры:

DL – координаты курсора на экране по горизонтали; DH – координаты курсора по вертикали;

BX – номер видеостраницы. Далее везде будет использоваться видеостраница 0.

Алгоритм процедуры Set_cursor приведен на рис.50.

На первом этапе алгоритма в регистр DH загружается номер строки дампа сектора (не путать со строкой экрана, номер которой еще предстоит получить). Для этого номер байта в секторе B делится на число байтов в строке, то есть на число 16. Такое деление рекомендуется выполнить путем сдвига содержимого регистра на четыре бита вправо.

На втором этапе в DL загружается номер байта в строке. Этот номер есть разность между номером байта в переменной Sector (переменная B) и таким же номером последнего байта в последней полностью заполненной строке.

165

Последний номер нетрудно получить сдвигом влево на четыре бита полученного на первом этапе номера строки дампа.

DH Å номер строки = B /16

DL Å номер байта в строке

DL Å номер символа на строке

DL Å DL + Nt

DL Å DL + 7

DH Å DH + 8

Установка курсора в точку

(DL,DH)

DL – координата курсора на экране по горизонтали

DH – координата курсора на экране по вертикали

B – номер байта в переменной Sector

Nt – номер тетрады в байте (0 – первая, 1 – вторая)

Рис. 50. Алгоритм процедуры Set_cursor

Далее производится преобразование номера байта в строке дампа в номер символа на строке экрана. Для этого на следующем этапе алгоритма полученный ранее номер в строке дампа умножается на три (два символа есть

166

шестнадцатеричные цифры для двух тетрад байта, а один символ – пробел). Далее к полученному номеру прибавляется величина Nt для того, чтобы курсор указывал на требуемую тетраду байта.

Далее все изображение дампа сдвигается ближе к центру экрана. Для этого к DL прибавляется 7, а к DH 8. Завершает работу по перемещению курсора соответствующий системный вызов.

П о л у ч и т е исходный текст процедуры Set_cursor и добавьте его в файл

Cursor.asm.

15.3. Выполнение команды

Для выполнения любой из четырех своих команд, выполняющих управление курсором, процедура Edit_sector вызывает свою дочернюю процедуру Edit_command. Алгоритм данной процедуры аналогичен алгоритму ранее разработанного интерпретатора команд – Command. Более того, идентичны тексты этих процедур. Идентичны и структуры используемых таблиц переходов. Естественно, что эти таблицы различаются числом строк, а также именами вызываемых процедур.

Имена процедур в новой таблице переходов: Cur_right (сдвиг курсора вправо), Cur_left (сдвиг курсора влево), Cur_top (сдвиг курсора вверх), Cur_down (сдвиг курсора вниз). Вот тексты двух из четырех процедур:

; Перемещение курсора на одну позицию влево

;

Cur_left:

 

cmp

[Nt], byte 0

 

je

.M1

 

dec

byte[Nt]

 

jmp

.Exit

.M1:

inc

byte[Nt]

167

dec byte[B]

.Exit: call Set_cursor ret

; Перемещение курсора на одну позицию вверх

;

Cur_top:

sub

[B], byte 16

call

Set_cursor

ret

 

Тексты двух других процедур Cur_right и Cur_down очень похожи, соответственно, на тексты процедур Cur_left и Cur_top.

Обратите внимание, что в данных процедурах нет проверок достижения переменной B своих крайних значений 0 и 255. Это объясняется тем, что длина данной переменной 1 байт, и поэтому при попытке уменьшить значение 0 в переменную будет записано число 255. А при попытке увеличить значение 255 в переменную будет записано число 0. Подобные изменения переменной B приведут к правильным перемещениям курсора на экране.

П о л у ч и т е исходный текст процедуры Edit_command и добавьте его в файл Disp_sec.asm. Исходные тексты процедур Cur_right, Cur_left, Cur_top, Cur_down добавьте в файл Cursor.asm.

15.4. Запись шестнадцатеричной цифры

Алгоритм процедуры Write_digit_sector, выполняющей запись в переменную Sector шестнадцатеричной цифры, приведен на рис.51.

Процедура Write_digit_sector имеет единственный входной параметр – в регистре DL передается величина шестнадцатеричной цифры, которая должна быть записана в позицию переменной Sector, на которую указывает курсор.

168

На первом этапе алгоритма проверяется на равенство нулю номера тетрады Nt. Если Nt = 0, то это значит, что редактируется первая тетрада байта. В этом случае данная тетрада сначала обнуляется (с помощью операции логического умножения), а затем в нее помещается двоичный код шестнадцатеричной цифры Z (с помощью операции логического сложения).

 

да

Nt=0

нет

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Sector(B)Å

 

 

Sector(B)Å

(Sector(B) ∩ 0Fh)

 

 

 

(Sector(B) ∩ F0h)

U Z0h

 

 

 

U 0Zh

 

 

 

 

 

 

 

Инициализация

курсора

Вывод

Sector

Сдвиг курсора вправо

B – номер байта в переменной Sector

Nt – номер тетрады (0 или 1) в редактируемом байте и U – операции логического умножения и сложения Z – шестнадцатеричная цифра

Рис. 51. Алгоритм процедуры Write_digit_sector

Если Nt = 1, то редактируется вторая тетрада байта, которая сначала обнуляется, а затем в нее помещается двоичный код шестнадцатеричной цифры

169

Z. Для кодирования данных двух этапов используются операторы сдвига, а также операторы логического умножения and и логического сложения or.

Назначение последних трех этапов алгоритма достаточно очевидно и не требует пояснений. П о л у ч и т е исходный текст процедуры

Write_digit_sector и добавьте его в файл Disp_sec.asm.

15.5. Лабораторная работа 13

Требуется написать и отладить описанные выше процедуры редактирования сектора. Процедура Edit_sector должна вызываться из диспетчера команд при нажатии клавиши <F4>.

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

16.ОПЕРАЦИИ С ФАЙЛАМИ

16.1.Файловая система FAT

Физический файл существует в ВС не обособленно, а как часть более крупной информационной единицы, называемой файловой системой (ФС). Эту систему образуют файлы и таблицы, расположенные на конкретном носителе ВП или расположенные на его части (в разделе или на логическом диске). Иногда в понятие файловой системы включают и совокупность подпрограмм ОС, выполняющих операции с файлами. Но мы, для избежания путаницы, этого делать не будем. Например, файловые системы,

170

поддерживаемые (обслуживаемые) DOS, имеют тип FAT. Этот тип объединяет три родственных типа файловых систем: FAT12, FAT16 и FAT32.

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

1)структура ФС;

2)состав атрибутов файла и место их хранения;

3)размещение элементов ФС на носителе;

4)место хранения информации о размещении файла;

5)длина простого имени файла.

Из перечисленных характеристик структура ФС и длина простого имени файла были рассмотрена ранее. Перейдем к рассмотрению других характеристик.

Файл-каталог ФС FAT состоит из 32-байтовых логических записей. В FAT12 и в FAT16 одна такая запись соответствует одному файлу. В ней находятся: простое имя файла (собственно имя и расширение имени); номер первого кластера логического диска, занимаемого данным файлом; атрибуты файла. В FAT32 каждому файлу соответствуют несколько 32-байтовых записей каталога. Структура первой из них аналогична записи каталога в FAT12 и в FAT16, а в последующих записях содержится длинное (до 255 байтов) простое имя файла. Таким образом, один и тот же файл может обрабатываться как системными вызовами, предназначенными для работы с короткими, так и системными вызовами для работы с длинными именами файлов.

Любая ФС содержит для каждого из своих файлов его атрибуты. Они используются самой ОС, а также пользователями и обрабатывающими программами. Наименьшее число атрибутов имеют файлы в ФС, поддерживаемых однопользовательскими однопрограммными системами. Например, в FAT файл имеет атрибуты: