Показаны сообщения с ярлыком архитектура. Показать все сообщения
Показаны сообщения с ярлыком архитектура. Показать все сообщения

Буфер клавиатуры

воскресенье, 25 апреля 2010 г. Автор: Vadim 0 коммент.

 

Буфер клавиатуры имеет объем 32 байта и располагается в памяти начиная с адреса 0040:001E. Он может накапливать до 15 нажатий на клавишу, независимо от того, являются ли они однобайтными кодами ASCII или двухбайтными расширенными кодами - буфер отводит по два байта для каждого нажатия клавиши (последнее нажатие, которое может быть максимально 16-м по счету, зарезервировано для клавиши <Enter>, которая разрешает исполнение введенной с клавиатуры команды для командного процессора COMMAND.COM). Для однобайтных кодов первый байт содержит код ASCII, а второй - скан-код клавиши. Для расширенных кодов первый байт содержит 0, а второй номер расширенного кода. Этот номер обычно совпадает со скан-кодом клавиши, но не всегда, поскольку некоторые клавиши могут комбинироваться с клавишами сдвига для генерации различных кодов.

Буфер устроен как циклическая очередь, которую называют также буфером FIFO (первый вошел - первым ушел). Однако не имеется определенной ячейки памяти, в которой находилось бы всегда начало строки в буфере. Вместо этого два указателя хранят позиции головы и хвоста строки символов, находящейся в буфере в текущий момент. Указатель головы указывает на позицию, занятую первым символом в буфере, а указатель хвоста - на позицию, следующую за последним символом (т.е. на первую свободную). Новые нажатия клавиш запасаются в позициях, на которые указывает указатель хвоста (в более старших адресах памяти), и соответственно обновляется указатель хвоста. После того, как израсходованы старшие адреса в буфере, новые символы начинают вставляться в самые младшие ячейки буфера; поэтому возможны ситуации, когда хвост буфера имеет меньший адрес, чем голова. После того как буфер заполнен, новые вводимые символы игнорируются, при этом обработчик прерываний клавиатуры выдает гудок через динамик. В этот момент указатель хвоста указывает на ячейку перед головой в циклической очереди буфера (куда можно занести нажатие <Enter>). Наконец, когда оба указателя равны, то буфер пуст. Поэтому чтобы очистить буфер клавиатуры, достаточно установить указатели но одно и тоже значение. На рис.2 показаны некоторые возможные конфигурации данных в буфере.

Указатели на голову и хвост расположены по адресам 0040:001A и 0040:001C, соответственно. Хотя под указатели отведено 2 байта, используется только младший байт. Значения указателей меняются от 1Eh до 3Ch, что соответствует позициям буфера в области данных BIOS.

Чтобы разрешить ввод 15 символов требуется, как уже было сказано, 16-я пустая позиция, 2 байта которой всегда содержат код возврата каретки (ASCII 13) и скан-код клавиши <Enter>, равный 28. Они поступают в буфер по нажатию клавиши <Enter>. Эта пустая позиция непосредственно предшествует голове строки символов.

Ввод данных с клавиатуры

Автор: Vadim 0 коммент.

 

Ввод данных с клавиатуры реализован с использованием промежуточного буфера ввода - "буфера клавиатуры" (специальной области памяти): все набираемые на клавиатуре символы сначала попадают в этот буфер, и уже отсюда они затем будут считываться программами DOS. Это означает, что можно досрочно ввести много данных и они не пропадут. Например, если в программе осуществляется ввод по одному символу, то все равно можно сразу набрать много символов - затем они будут считываться из буфера по одному. Кроме того, при вводе допускается редактирование вводимого текста: при нажатии клавиши "стрелка влево" или Backspase уничтожается последний набранный символ, а при нажатии Esc уничтожается весь набранный текст (при работе COMMAND.COM редактирование возможно пока не нажата клавиша Enter; при нажатии Enter командный процессор исполняет введенную команду). Рассмотрим путь символов от клавиатуры до буфера ввода подробнее.

Клавиатура содержит встроенный микропроцессор, который воспринимает каждое нажатие или отпускание клавиши и выдает скан-код в порт A (60h) микросхемы контроллера клавиатуры, расположенной на системной плате. Скан-код - это однобайтное число (в определенных случаях - последовательность однобайтных чисел), однозначно определяющее нажатую вами клавишу. Клавиатура вырабатывает различные сканируемые коды в зависимости от того, нажимается или отпускается клавиша. Младшие 7 битов скан-кода представляют идентификационный номер, присвоенный каждой клавише, а старший бит говорит о том, была ли клавиша нажата или отпущена: при нажатии старший бит (бит 7) содержит 1, при отпускании - 0. Например, 7-битный скан-код клавиши B - 48, или 0110000 в двоичной системе. Когда эта клавиша нажимается, то в порт A интерфейса посылается код 10110000, а когда ее освободили - код 00110000. AT работает немного по-другому, посылая в обоих случаях один и тот же скан-код, но предваряя его кодом F0h, когда клавиша отпускается. Отличие "кодов нажатия" и "кодов освобождения" позволяет компьютеру различать комбинации из нескольких клавиш, т.е. когда при удержании одной клавиши одновременно нажимается другая. В этом случае код освобождения от первой клавиши не поступает, и компьютер таким образом "знает", что она не освобождалась, т.е. что вводится комбинация, и правильно распознает ее. Комбинации используются при смене регистра клавиатуры (например, "a" и "Shift-a", т.е. "A"), реализации ввода "горячих клавиш" и т.д.

Дублируемые клавиши дифференцируются клавиатурой путем использования для них более длинных скан-кодов, состоящих из нескольких байтов. Например, две клавиши смены регистра Alt имеют различные сканируемые коды: левая клавиша Alt имеет сканируемый код, равный 38h, в то время как правая клавиша Alt имеет 2-байтовый сканируемый код E0h 38h.

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

Микросхема контроллера клавиатуры управляет вводом информации с клавиатуры в процессор. Всякий раз, когда вы нажимаете или отпускаете ту или иную клавишу, контроллер клавиатуры формирует ее скан-код (очередной его байт) в порте A и генерирует прерывание 9 (запрос на процессор поступает по линии IRQ1). Процессор моментально прекращает свою работу и переключается на выполнение подпрограммы обработчика прерывания 9, содержащуюся в ROM BIOS. Обработчик считывает байт из порта A и осуществляет его обработку. Когда поступает код от клавиши сдвига или переключателя, то изменение статуса записывается в память (по адресам 0040:0011 и 0040:0012). Во всех остальных случаях скан-код трансформируется в код символа ASCII, при условии, что он подается при нажатии клавиши (в противном случае скан-код отбрасывается). Конечно, процедура сначала определяет установку клавиш сдвига и переключателей, чтобы правильно получить вводимый код (это "a" или "A" ?). После этого введенный код помещается в буфер клавиатуры. На рис.1 показан путь, который проходит нажатие на клавишу перед тем, как попасть в Вашу программу.

Имеется два типа кодов символов: коды ASCII и расширенные коды. Коды ASCII - это байтные числа, используемые для представления символов внешнего алфавита ЭВМ. Этот набор включает обычные символы пишущей машинки, а также ряд специальных букв и символов псевдографики. ASCII коды включают также 32 управляющих кода, которые обычно используются для передачи команд периферийным устройствам, а не выводятся как символы на экране; правда, каждый из них имеет соответствующее символьное представление, которое может быть выведено на дисплей с использованием прямой адресации дисплейной (видео) памяти.

Второй набор кодов, расширенные коды, присвоен клавишам или комбинациям клавиш, которые не имеют представляющего их символа ASCII, таким как функциональные клавиши или комбинации с клавишей Alt. Расширенные коды имеют длину 2 байта, причем первый байт всегда 0. Второй байт - определенный номер расширенного кода. Например, код 0:30 представляет Alt-A. Начальный номер позволяет программе определить, принадлежит ли данный код набору ASCII или расширенному набору.

Имеется несколько комбинаций клавиш, которые выполняют специальные функции и не генерируют скан-коды. Эти комбинации включают Ctrl-Break, Ctrl-Alt-Del и PrtSc, плюс SysReq для AT. Эти исключения приводят к заранее предопределенным результатам. Все остальные нажатия клавиш должны интерпретироваться Вашей программой, и если они имеют специальное назначение, скажем сдвинуть курсор влево, то Ваша программа должна содержать машинные команды, обеспечивающие достижение этого эффекта.

К счастью, операционная система предоставляет различные процедуры (служебные функции DOS 01h, 06h, 07h, 08h, 0Ah, 0Bh и 0Ch прерывания 21h ) для чтения кодов из буфера клавиатуры, включая средства для получения сразу целой строки. Поскольку эти процедуры позволяют делать практически все, что Вы можете пожелать, то практически бессмысленно писать свои процедуры обработки ввода с клавиатуры и можно пользоваться готовыми функциями DOS.

МАНИПУЛЯТОР МЫШЬ

Автор: Vadim 0 коммент.

Манипулятор мышь (в дальнейшем, просто мышь) является средством, позволяющим пользователю достаточно удобно осуществлять управление прикладными программами. Как правило, мышь соединена с ПЭВМ через последовательный интерфейс. Прикладные программы, связывающиеся через интерфейс с мышью, делают это через обращение к драйверу Microsoft, например GMOUSE.COM. Все обращения к драйверу происходят через прерывание 33h.

Прерывание 33h имеет ряд функций, которые выбираются с помощью загрузки номера функции в регистр AX. Основные функции будут приведены ниже.

Функция 00h: инициализация мыши. Если мышь инициализирована, то в регистре AX возвращается значение FFFFh, а в регистре BX - число клавиш мыши. Если инициализации не происходит, то в регистре AX возвращается значение 0000h.

Функция 01h: показать указатель мыши.

Функция 02h: спрятать указатель мыши.

Функция 03h: получить текущие координаты указателя мыши и состояние кнопок. Координаты указателя соответствует виртуальному экрану. На практике, обычно, они содержат положение пикселя в графическом режиме или умноженные на 8 координаты в текстовом режиме. Отсчет графических координат начинается от 0. Текстовые координаты отсчитываются от 1. Эта функция возвращает в регистре CX координату x, а в регистре DX координату y, в регистре BX - состояние кнопки (бит 0 - левая кнопка нажата, если установлена; бит 1 - средняя кнопка нажата, если установлена; бит 2 - правая кнопка нажата, если установлена).

Функция 04h: установить позицию указателя. В регистр CX пересылается координата x, а в регистр DX координата y. Установленная позиция указателя будет игнорироваться, если она находится внутри области исключения (см. функцию 07h и 08h). Координаты задаются всегда в пикселях, где (0,0) - координата верхнего левого угла виртуального экрана.

Функция 05h: получить информацию о нажатии клавиши. В регистр BX пересылается номер кнопки (0 - левая кнопка, 1 - правая кнопка, 2 - средняя кнопка). В регистр AX возвращается состояние кнопки (бит 0 - левая кнопка нажата, если установлена; бит 1 - средняя кнопка нажата, если установлена; бит 2 - правая кнопка нажата, если установлена). В регистр BX возвращается счетчик нажатия клавиши, CX - координата x последнего нажатия, DX - координата y последнего нажатия. После обращения к этой функции счетчик нажатия клавиши сбрасывается.

Функция 06h: получить информацию об отжатии клавиши. В регистр BX пересылается номер кнопки (0 - левая кнопка, 1 - правая кнопка, 2 - средняя кнопка). В регистр AX возвращается состояние кнопки (бит 0 - левая кнопка отжата, если установлена; бит 1 - средняя кнопка отжата, если установлена; бит 2 - правая кнопка отжата, если установлена). В регистр BX возвращается счетчик отжатий клавиши, CX - координата x последнего отжатия клавиши мыши, а DX - координата y последнего отжатия клавиши мыши. После обращения к этой функции счетчик отжатия клавиши сбрасывается.

Функция 07h: установить горизонтальное ограничение для указателя мыши. В регистр CX пересылается минимальное значение координаты x, в регистр DX - максимальное значение координаты x.

Функция 08h: установить вертикальное ограничение для указателя мыши. В регистр CX пересылается минимальное значение координаты y, в регистр DX - максимальное значение координаты y.

Функция 09h: установить форму указателя мыши в графическом режиме. По умолчанию используется указатель типа стрелки. В ES:DX пересылают адрес буфера изображения. Длина буфера изображения 64 байта. Байты с 32 по 64 определяют вид курсора, а байты с 0 по 31 определяют прозрачность курсора. Они рассматриваются как битовая маска 16´16 каждый бит которой маскирует пиксели экрана. При создании изображения драйвер предварительно получает информацию о 16´16 пикселях соответствующего места экрана и к каждому пикселю применяется операция AND с маской экрана, а затем к полученному результату - операция XOR с маской изображения. Приведенный ниже пример показывает формирование курсора в графическом режиме в виде прямоугольника с тонкой прозрачной полоской в середине.

program testmouse;

uses dos,graph;

var

reg:registers;

res1,res2,i,res3,res4:byte;

buf : array [0..63] of byte;

gd,gm:integer;

begin

FOR i:=32 TO 64 DO

buf[i]:=255;

FOR i:=0 TO 31 DO

buf[i]:=1;

gd:=detect;

initgraph(gd,gm,'');

reg.AX:=1;

intr($33,reg);

reg.ax:=9;

reg.es:=seg(buf);

reg.dx:=ofs(buf);

intr($33,reg);

.

.

.

closegraph;

end.

В регистр BX заносится смещение вправо (в пикселях) из левого верхнего угла указателя, пикселя изображения рассматриваемого драйвером в качестве текущей позиции. В регистр CX заносится смещение вниз (в пикселях) из левого угла указателя, пикселя изображения рассматриваемого драйвером в качестве текущей позиции.

Функция 0Ah: установить вид указателя мыши в текстовом режиме. В регистр BX заносят 0, если выбирают курсор, используемый в программе, и 1, если выбирают стандартный курсор. Если указатель генерируется программой, то в регистр CX заносятся биты определяющие маску AND, а в регистр DX заносятся биты определяющие маску XOR по следующему принципу. Биты 0-7 - код символа; биты 8-10 цвет символа; бит 11 - бит интенсивности; биты 12-14 - цвет фона; бит 15 - бит мерцания.

Функция 10h: установить область исключения указателя. В регистр CX пересылают значение левой верхней координаты x, в DX - значение левой верхней координаты y, в SI - значение правой нижней координаты x, в DI - значение правой нижней координаты y. Эта функция определяет область исключения отображения указателя мыши. Область исключения отменяется обращением к функции 00h или 01h, или другим обращением к этой функции.

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

Функция 15h: получить размер сохраненного буфера состояния мыши. В регистр BX возвращается размер буфера в байтах.

Функция 16h: сохранить состояние драйвера мыши. В ES:DX заносится адрес буфера. Под буфер выделяется 64 байта.

Функция 17h: восстановить состояние драйвера мыши. В ES:DX заносится адрес буфера.

Функция 1Dh: установить текущую видеостраницу для указателя мыши. В регистр BX заносится номер видеостраницы. Допустимые номера страницы зависят от активного режима визуального отображения.

Функция 1Eh: получить текущую видеостраницу для указателя мыши. В регистр BX возвращается номер текущей видеостраницы для указателя мыши.

Функция 1Fh: отключить драйвер мыши. Если отключение драйвера прошло успешно, то в регистр AX заносится значение 001Fh, а в ES:BX - адрес драйвера. Если драйвер не отключен, то в регистр AX возвращается значение FFFFh.

Функция 20h: повторное включение драйвера мыши.

Функция 24h: получить информацию о мыши. Возвращаются следующие значения:

BH - старший номер версии драйвера; BL - младший номер версии драйвера; CH - тип мыши (1 - bus mouse, 2 - serial mouse, 3 - InPort mouse, 4 - PS/2 mouse, 5 - HP mouse); CL - номер аппаратного прерывания.

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

Procedure test;

{чтение мыши и клавиатуры}

type signal=record

case mouse:boolean of

true:(left,right:boolean;

{состояние клавиш мыши

dx,dy:word ;{ее перемещение });

false: (asc,ext:byte;

{ ASC- и расширенный коды }

status:word;

{флаги клавиатуры});

end;

{поле mouse показывает, сигнал от мыши или клавиатуры}

var ready:boolean;

begin

ready:=false; {ожидание команды}

with signal_t(signal) do

repeat

if mouse_sig then begin

mouse:=true;

r.ax:=11;intr($33,r);dx:=r.cx;dy:=r.dx;

r.ax:=3; intr($33,r);

left:=r.bx and 1 <>0;

right:=r.bx and 2 <>0;

mouse_sig:=false;

ready:=true; end

else {если мышь не трогали - опрос клавиатуры}

begin r.ah:=$11; intr($16,r);

{если не расширенная клавиатура, вызывайте функцию 1}

if r.flags and 64 = 0 then begin

{если буфер клавиатуры не пуст}

mouse:=false;

status:=memw[$40:$17]; {флаги клавиатуры}

repeat

r.ah:=$10;intr($16,r);

asc:=r.al; ext:=r.ah;

r.ah:=$11; intr($16,r);

ready:=r.flags and 64 <>0;

{очистка буфера и запоминание кода клавиши}

until ready; end;

end

until ready;

end;

ВНУТРЕННИЕ РЕГИСТРЫ

воскресенье, 31 января 2010 г. Автор: Vadim 0 коммент.

На рис. 1.2 пока­заны три группы регистров данных, и адресов, 16-битовый указатель команд IP (Instruction Pointer) и 16-битовый регистр флагов.

clip_image002[4]

РЕГИСТРЫ ДАННЫХ

В зависимости от того, чем Вы оперируете: 16-битовыми словами или 8-битовыми байтами, регистры данных можно рассматривать как четыре 16-бито­вых или восемь 8-битовых регистров. В первом случае регистры имеют имена АХ, ВХ, СХ, DX. Эти регистры образованы из 8-битовых регистров AL, АН, BL, ВН, CL, СН, DL и DH. Здесь L и Н означают младшие (low-order) и старшие (high-order) байты 16-битовых регистров. Например, регистры AL и АН образуют соответственно младший и старший байты регистра АХ.

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

регистр АХ, аккумулятор (accumulator), используется при умножении и делении слов, в операциях ввода-вывода и в некоторых операциях над строками; регистр AL используется при выполнении аналогичных операций над байтами, а также при преобразовании-десятичных чисел и выполнении над ними арифмети­ческих операций;

регистр АН используется при умножении и делении байтов;

регистр ВХ, Базовый регистр (base register), часто используется при адресации данных в памяти;

регистр СХ, счетчик (count register), используется как счетчик числа повторений цикла и в качестве номера позиции элемента данных при операциях над строка­ми. Регистр CL используется как счетчик при операциях сдвига и циклического сдвига на несколько битов;

регистр DX, регистр данных (data register), используется при умножении и деле­нии слов. Кроме того, в операциях ввода-вывода он используется как номер порта.

Программисты, имеющие опыт работы с микропроцессорами 8080 и 8085, должны заметить, что АН - единственный регистр микропроцессора 8088, не имеющий ана­лога в этих микропроцессорах. Остальные регистры использовались в них под другими именами; так, в микропроцессоре 8080 регистру AL соответствует регистр А, а регистрам ВХ, СХ и DX соответствуют регистры HL, ВС и DE.

Только регистры данных могут использоваться и как 16-битовые, и как 8-бито­вые. Все регистры остальных групп - 16-битовые.

РЕГИСТРЫ СЕГМЕНТОВ

Ранее уже говорилось, что в ЭВМ, сконструированных на базе мик­ропроцессоров 8086 и 8088, программы и данные хранятся в отдельных областях памяти. Эти области (или сегменты) могут иметь объем до 64 Кбайт. Микропроцес­сор 8088 может иметь дело одновременно с четырьмя сегментами. Начальные адре­са этих сегментов содержатся в его четырех регистрах сегментов. Эти регистры выполняют следующие функции:

регистр сегмента команд CS (code segment) указывает на сегмент, содержащий текущую исполняемую программу. Для вычисления адреса следующей исполня­емой команды микропроцессор 8088 добавляет к содержимому регистра CS (умноженному на 16) содержимое указателя команд IP;

регистр сегмента стека SS (stack segment) указывает на текущий сегмент стека. Стек представляет собой область памяти, используемую для временного хра­нения данных и адресов. Микропроцессор 8088 использует стек для хранения адреса возврата из текущей подпрограммы, но стек можно использовать также для восстановления содержимого регистров, изменяемых при работе програм­мы. Позже мы рассмотрим стеки более подробно;

регистр сегмента данных DS (data segment) указывает на текущий сегмент дан­ных, обычно содержащий используемые в программе переменные; регистр дополнительного сегмента ES (extra segment) указывает на текущий дополнительный сегмент, который используется при выполнении операций над строками.

РЕГИСТРЫ УКАЗАТЕЛЕЙ И ИНДЕКСОВ

Вспомните, что для вычисления адреса команды в сегменте команд микропроцессор 8088 извлекает номер блока памяти из регистра CS, а смеще­ние- из регистра IP. Подобным образом за счет выбора номера блока из соответ­ствующего регистра сегмента, а смещения - из другого регистра осуществляется доступ к данным других сегментов. Для доступа к сегменту данных микропроцес­сор 8088 извлекает номер блока из регистра DS, а смещение - из регистра ВХ или индексного регистра (SI или DI). Для доступа к сегменту стека микропроцессор 8088 извлекает номер блока из регистра SS, а смещение - из регистра указателя (SP или BP). Выбирая номер блока из регистра ES, микропроцессор может также полу­чить доступ к дополнительному сегменту (подробнее об этом см. в гл. 2).

УКАЗАТЕЛЬ КОМАНД

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

Одна из них, интерфейс шины (Bus Interface Unit), извлекает команды из памяти и осуществляет передачу данных между исполнительными компонентами и "внеш­ним миром". Другая компонента, операционный блок (Execution Unit), только исполняет команды. Так как эти компоненты независимы, то интерфейс шины может извлекать новую команду из памяти в то самое время, когда операционный блок исполняет ранее извлеченную команду.

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

clip_image002

Так как интерфейс шины не знает порядка исполнения команд программы, то он всегда извлекает команды с последовательно возрастающими адресами. Поэто­му операционному блоку приходится ждать извлечения команды из памяти толь­ко в тех случаях, когда в программе управление передается не следующей коман­де, а какой-то другой. Тогда операционный блок ожидает, пока интерфейс шины не освободит конвейер и не извлечет требуемую команду. Тогда и только тогда микропроцессор 8088 ждет подобно многим другим микропроцессорам извлечения каждой команды. На рис. 1.3 показано параллельное извлечение и исполнение команд в микропроцессоре 8088.

Так как микропроцессор 8088 работает столь необычным образом, то специалис­ты фирмы Intel подчеркнули отличие своего регистра "следующего исполняемого адреса" от регистров "следующего извлекаемого адреса" других производителей микропроцессоров, назвав его указателем команд (IP - instruction pointer) вместо обычного счетчика команд (PC - program counter). Так как регистр IP имеет столь специфическое назначение, то Вы не можете выполнять арифметические операции над его содержимым. Однако микропроцессор 8088 имеет команды, одни из кото­рых изменяют содержимое регистра IP, а другие помещают его в стек и извлекают обратно.

ФЛАГИ

В программе нередко требуется принять решение на основании резуль­тата только что исполненной микропроцессором 8088 команды. Например Вам может понадобиться выполнить одни действия, если результат сложения оказался нулем (например, напечатать. "Баланс равен нулю!" в программе для бухгалтер­ских расчетов), и совсем другие действия в противном случае.

В 16-битовом регистре флагов фиксируется информация о текущем состоянии дел, которая может помочь Вашей программе принять решение. Шесть битов регистра служат для хранения состояний, а три других могут быть использованы для программного управления режимом работы микропроцессора 8088.

На рис. 1.4 показано, как эти девять- флагов размещены в регистре флагов. Флаги имеют следующие значения:

[.Бит 0, флаг переноса CF(carry flag), равен 1, если произошел перенос единицы при сложении или заем единицы при вычитании. В противном случае он равен нулю. Кроме того, CF содержит значение бита, который при сдвиге или цикли­ческом сдвиге регистра или ячейки памяти вышел за их границы, и отражает результат операции сравнения. Наконец, CF служит индикатором результата умножения; детали см. в описании бита 11 (OF).

2.Бит 2,флаг четности PF(parity flag), равен 1, если в результате операции полу­чено число с четным числом единиц в его битах. В противном случае он равен нулю. ФлагРГ в основном используется в операциях обмена данными.

3. Бит 4, вспомогательный флаг переноса AF (auxiliary carry flag), аналогичен флагу CF, только контролирует перенос или заем для третьего бита данных. Полезен при выполнении операций над упакованными десятичными числами.

4. Бит 6, флаг нуля ZF(zero flag),равен 1, если в результате операции получен нудь; ненулевой результат c6pacbiBaerZF в нуль.

5. Бит 7, флаг знака SF (sign flag), имеет значение только при операциях над числами со знаком. Флаг SF равен 1, если в результате арифметической или логической операции, сдвига или циклического сдвига получено отрицательное число. В противном случае он равен нулю. Иными словами, SF дублирует стар­ший (знаковый) бит результата независимо от того, имеет результат длину 8 или 16 битов.

6. Бит 8, флаг трассировки TF (trap flag), разрешает микропроцессору 8088 испол­нять програму "по шагам" и используется при отладке программ.

7. Бит 9, флаг прерывания IF (interrupt enable flag), разрешает микропроцессору 8088 реагировать на прерывания от внешних устройств. Сбрасывание IF в нуль заставляет микропроцессор 8088 игнорировать прерывания до тех пор, пока F не станет равным 1.

8. Бит 10, флаг направления DF (direction flag), заставляет микропроцессор 8088 уменьшать на единицу (DF = 1) или увеличивать на'единицу(ВР = 0) регистр(ы) индекса после выполнения команды для работы со строками. Если DF = 0, то микропроцессор 8088 будет обрабатывать строку "слева направо" (от младших адресов к старшим). Если DF = 1, то обработка пойдет в обратном направлении (от старших адресов к младшим или справа налево).

9. Бит И, флаг переполнения OF (overflow flag), в первую очередь служит инди­катором ошибки при выполнении операций над числами со знаком. Флаг OF равен 1, если результат сложения двух чисел с одинаковым знаком или резуль­тат вычитания двух чисел с противоположными знаками выйдет за пределы допустимого диапазона значений операндов. В противном случае он равен 0. Кроме того, OF = 1, если старший, (знаковый) бит операнда изменился в резуль­тате операции арифметического сдвига. В противном случае он равен 0.

В сочетании с флагом CF флаг OF указывает длину результата умножения. Если старшая половина произведения отлична от нуля, то OF hCF равны 1; в противном случае оба эти флага равны 0.

Наконец,OF = 0, если частное от деления двух чисел переполняет результирую­щий регистр.

clip_image004

На рис. 1.4 заштрихованы позиции неиспользуемых битов (1, .3, 5 и 12 - 15). Когда бы Вы ни прочитали значение регистра флагов, эти биты будут нулевыми.

Не делайте ошибок, рассчитывая, что в кождый момент времени флаги должны быть в определенном состоянии. У микропроцессора 8088 имеются команды для установки или сброса флагов. Если состояние флагов может быть неоднозначным, используйте эти команды.

У микропроцессора 8088 есть команды условной передачи управления, которые проверяют состояния флагов переноса CF, четности PF, нуля ZF, знака SF и переполнения OF. В зависимости от результата проверки выполнение программы продолжается либо со следующей команды, либо с некоторой другой ячейки памяти.

ОБЩИЕ СВЕДЕНИЯ О МИКРОПРОЦЕССОРЕ 8088

Автор: Vadim 0 коммент.

Внутри микропроцессора 8088 информация содержится в группе 16-битовых элементов, называемых регистрами. Всего он имеет 14 регистров: 12 регистров данных и адресов и в дополнение к ним указатель команд (регистр адре­са команд) и регистр состояния (регистр флагов). Можно подразделить 12 регистров данных и адресов на три группы по четыре регистра, а именно на регистры данных, регистры указателей и индексов и регистры сегментов.

АДРЕСАЦИЯ

Так как у микропроцессора 8088 указатель команд и адресные ре­гистры имеют по 16 битов, то можно подумать, что он способен адресоваться к памяти объемом не более 64 байт (65 536 байт), т. е. имеет стандартный для 8-бито-' вых микропроцессоров диапазон адресов. Однако на самом деле микропроцессор 8088 всегда генерирует 20-битовые адреса. Он делает это за счет добавления 16-би­тового смещения к содержимому регистра сегмента, умноженному на 16. Таким образом,

физический адрес = смещение + 16 • (регистр сегмента).

В действительности микропроцессор 8088 вместо умножения на 16 использует содержимое регистра сегмента так, как если бы оно имело четыре дополнительных нулевых-бита (рис. 1. 1). Добавление нулей аналогично умножению, поскольку при каждом сдвиге на одну позицию влево двоичное число удваивается. Следователь­но, перемещение значения регистра сегмента на четыре позиции влево умножает его на 16:2 • 2 • 2 • 2 = 16.

Например, если смещение адреса имеет значение ЮН, где суффикс Н обозначает шестнадцатеричное число, а регистр сегмента содержит 2000Н, то микропроцессор 808С произведет вычисление физического адреса следующим образом (операнды показаны в двоичном виде):

0000 0000 0001 0000 (смещение) + 0010 0000 0000 0000 0000 (номер блока) 0010 0000 0000 0001 0000 (физический адрес).

Следовательно, мы получим 20-битовый адрес ячейки памяти 200ЮН.

Имея в своем распоряжении 20-битовый адрес, микропроцессор 8088 может получить доступ к любому из 1 048 576 байт. .(Данное значение называется "мега­байт" (Мбайт); 1 Мбайт = 1024 Кбайт.) Это в 16 раз превышает диапазон адресов микропроцессора 8088!

15 О

Смещение

clip_image002[4]

СЕГМЕНТЫ И СМЕЩЕНИЯ

У большинства микропроцессоров адрес ячейки памяти представляет собой одно число. А у микропроцессора 8088 адрес каждой ячейки памяти задается двумя числами: номером блока и смещением. Такой странный метод адресации обусловлен тем, что команды программы для микропроцессора 8088 и ее данные должны располагаться в разных частях памяти, другими словами, в разных сег­ментах. Если, например, Вам требуется адресоваться к ячейке с данными, то микропроцессору 8088 понадобится адрес блока памяти, с которого начинается сегмент данных (из регистра сегмента данных), и позиция желаемой ячейки в этом сегменте (ее смещение). Вспомните, как ищут в городе чей-нибудь дом: сначала находят улицу (считайте ее сегментом), а затем дом с нужным номером (смеще­нием) на этой улице.

К счастью, Вам достаточно задавать только смещение, а номер блока микропро­цессор 8088 выберет сам. Несколько позже мы обсудим это обстоятельство более детально.

ВОЗМОЖНОСТИ ПРОГРАММИРОВАНИЯ

Микропроцессор 8088 обладает впечатляющими возможностями прог­раммирования. Они пришлись особенно по душе тем программистам, которым ранее приходилось "бороться" с 8-битовыми микропроцессорами. Действительно, микропроцессор 8088 может выполнять арифметические операции над двоичными числами со знаком и без знака, длиной в 8 или 16 битов, а также над десятичными числами, хранящимися как в упакованном (по две цифры в байте), так и в неупа­кованном (по одной цифре в байте) виде. Он может также оперировать строками (например, сообщениями) длиной до 64 Кбайт.

Система команд микропроцессора 8088 содержит 92 основных типа команд и предусматривает семь различных способов адресации или режимов доступа к данным. Комбинации типов команд, режимов адресации (имеющие множество комбинаций операндов) и различных типов данных, которые мы только что упоми­нали, образуют тысячи команд, которые могут быть выполнены микропроцессором 8088. Действительно, сочетание всех этих свойств позволяет микропроцессору 8088 обеспечивать вдвое большую производительность по сравнению с 8085, если оба они работают с одинаковой скоростью.

МЕРА СКОРОСТИ

Как и электронные часы, микропроцессоры управляются кварцевым генератором. Кварцевый генератор испускает импульсы со стабильной фиксиро­ванной частотой, задающей скорость работы микропроцессора. В персональных ЭВМ PC и PC/XT кварцевый генератор испускает 4 770 000 импульсов в секунду.

Специалисты по вычислительной технике пользуются другой единицей измере­ния: числом колебаний в секунду, или герцами. Импульсы в секунду, колебания в секунду и герцы означают одно и то же, но в этой книге мы будем использовать термин "герц". Таким образом, персональная ЭВМ PC имеет тактовый генератор с частотой 4 770 000 Гц (4,77 МГц).

При частоте 4,77 МГц (4 770 000 колебаний в секунду) тактовый генератор персональной ЭВМ PC "тикает" каждые 210 не. Мы будем называть это значение циклом тактового генератора ЭВМ.

Самая быстрая команда (например, копирование содержимого одного регистра в другой регистр) выполняется за два цикла, или за 420 не. Самая медленная команда, деление двух 16-битовых чисел со знаком, выполняется за 206 циклов тактового генератора, или примерно за 43 мкс. Как видите, даже самая медленная команда выполняется всего за 0, 000043 с!

ОБЛАСТЬ ПОРТОВ ВВОДА-ВЫВОДА

В дополнение к области памяти объемом в 1 Мбайт микропроцессор 8088 может адресоваться к внешним устройствам через 65 536 (64 К) портов вво­да-вывода. Он имеет специальные команды ввода-вывода, которые позволяют Вам иметь непосредственный доступ к первым 256 портам (от 0 до 255). Другие команды позволяют Вам получить косвенный доступ к порту с помощью занесения идентифицирующего его номера (от 0 до 65 535) в регистр данных. Подобно ячей­кам памяти любой порт может быть 8- или 16-битовым.

РАСПРЕДЕЛЕНИЕ ПАМЯТИ

Большая часть адресного пространства в 1 Мбайт доступна для систем­ных и прикладных программ, но некоторые ячейки с самыми старшими и самыми младшими адресами используются микропроцессором 8088 для специальных целей. Шестнадцать старших байтов памяти отводятся под команды начальной загрузки системы, которые используются микропроцессором 8088 в момент вклю­чения питания. Первые 1024 ячейки отведены под адреса программ, которые исполняются микропроцессором 8088 при прерывании его работы внешним устрой­ством.

ПРЕРЫВАНИЯ

Время от времени всем нам приходится сталкиваться с прерываниями. Одни прерывания нам приятны, другие неприятны, третьи безразличны. При жела­нии Вы можете игнорировать некоторые прерывания, не обращая внимания, ска­жем, на телефонный или дверной звонок или на ребенка, дергающего Вас за рукав. (Да нет, игнорировать ребенка практически невозможно!) На прерывания других видов Вы просто обязаны реагировать; например, если Вы прокололи шину на железнодорожном переезде, то должны немедленно что-то предпринять.

Прерывания по сути являются требованиями к Вам обратить на них внимание. Аналогично периферийные устройства вычислительной системы могут потребо­вать, чтобы процессор "обратил на них внимание". Поэтому событие, которое заставляет процессор приостановить выполнение своей программы для выполне­ния некоторой затребованной деятельности, называется прерыванием.

Прерывания существенно увеличивают эффективность вычислительной систе­мы, поскольку они позволяют внешним устройствам "обращать на себя внимание" процессора только по мере надобности. Если бы в системе не было прерываний, тс процессору пришлось бы периодически проверять, не требует ли обслуживания какое-нибудь устройство системы. Это похоже на телефон без звонка: пользуясь им, Вам приходилось бы очень часто снимать трубку и проверять, не пытается ли кто-нибудь в Вами соединиться?

ТИПЫ ПРЕРЫВАНИЙ

Микропроцессор 8088 может обрабатывать прерывания двух видов: одни он может игнорировать, а другие обязан обслужить как можно скорее. Преры­вания могут быть инициированы внешними устройствами, например дисководами и. другими высокоскоростными периферийными устройствами; они могут быть также инициированы специальными командами или, в определенных ситуациях, самим микропроцессором 8088.

Микропроцессор 8088 может распознать 256 различных прерываний. Каждому из них однозначно соответствует код типа, по которому микропроцессор иденти­фицирует прерывание. Он использует этот код (целое число от 0 до 255) в качестве указателя ячейки, находящейся в области памяти с младшими адресами. Эта ячейка содержит адрес программы обработки данного прерывания, называемый вектором прерывания.

Некоторые из этих 256 прерываний используются системным программным обеспечением, поставляемым фирмой IBM к своим персональным ЭВМ IBM PC, а именно резидентной частью операционной системы (называемой BIOS), дисковой операционной системой DOS и интерпретатором языка Бейсик. Остальные прерыва­ния можно использовать по своему усмотрению. Более детально прерывания обсуждаются в гл. 6.

АДРЕСНАЯ ШИНА И ШИНА ДАННЫХ

Микропроцессор 8088 выполнен в виде интегральной микросхемы с 40 выводами, 20 из которых служат для вывода адресов ячеек памяти и образуют так называемую адресную шину. Первые 8 проводников адресной шины используются также для ввода данных в микропроцессор и вывода данных из него; они образуют 8-битовую шину данных микропроцессора 8088. Такое совмещение называется мультиплексированием шины данных и адресной шины. (Старшие четыре проводника адресной шины также мультиплексированы: по ним в микропроцессор поступает информация о состоянии операций с памятью и устройствами ввода-вы­вода.)