Книга Код. Тайный язык информатики, страница 76. Автор книги Чарльз Петцольд

Разделитель для чтения книг в онлайн библиотеке

Онлайн книга «Код. Тайный язык информатики»

Cтраница 76

Значение

E3h

XTHL HL,[SP]

Поменять местами «верхний» элемент стека и HL

EBh

XCHG HL, DE

Поменять местами DE и HL

Из всех команд перехода для процессора 8080 пока я описал только PCHL. Как вы помните из главы 17, процессор предусматривает регистр под названием «счетчик команд», содержащий адрес ячейки памяти, из которой процессор извлекает следующую команду, подлежащую выполнению. Как правило, счетчик команд заставляет процессор выполнять команды, сохраненные в памяти, последовательно. Однако так называемые команды перехода, или ветвления, позволяют процессору отклониться от этого главного курса. Эти команды загружают в счетчик команд другое значение, поэтому следующая команда извлекается процессором из какой-то другой области памяти.

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

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

Прежде чем продемонстрировать эти команды, хочу познакомить вас с двумя другими типами команд, имеющих отношение к переходу. Первая — CALL (вызов), она аналогична команде перехода, за исключением того, что перед загрузкой нового адреса в счетчик команд процессор сохраняет предыдущий адрес. Где он сохраняет этот адрес? Разумеется, в стеке!

Эта стратегия подразумевает, что команда вызова сохраняет информацию о том месте, откуда был совершен переход. Сохраненный адрес позволяет процессору вернуться в исходное местоположение. Команда для совершения обратного перехода называется RET (Return — вернуться). Она удаляет из стека 2-байтное значение и загружает его в счетчик команд.

Команды CALL и RET — чрезвычайно важные функции любого процессора, позволяющие программисту реализовывать подпрограммы, которые являются часто используемыми фрагментами кода. (Под словом «часто» обычно я имею в виду «более одного раза».) Подпрограммы — основные организующие элементы программ на языке ассемблера.

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

Набор команд, позволяющих перемножить два байта, идеально подходит на роль подпрограммы. Давайте рассмотрим одну из них. В главе 17 подлежащие перемножению байты и произведение хранились в определенных ячейках памяти. Приведенная далее подпрограмма 8080 умножает байт в регистре B на байт в регистре C и помещает 16-битное произведение в регистр HL.

Код. Тайный язык информатики

Обратите внимание: первая строка подпрограммы начинается с метки Multiply. Эта метка соответствует адресу ячейки памяти, в которой расположена подпрограмма. Подпрограмма начинается с двух команд PUSH. Как правило, она пытается сохранить (а в дальнейшем восстановить) значения любых регистров, которые могут ей потребоваться.

Затем подпрограмма записывает значение 0 в регистры H и L. Для этого вместо команды SUB можно было бы использовать команду MVI (Move Immediate — переместить непосредственно), однако в этом случае потребовались бы четыре команды, а не две. После выполнения подпрограммы в паре регистров HL будет содержаться произведение.

После этого подпрограмма перемещает содержимое регистра B (множитель) в A и проверяет, не равно ли оно 0. Если оно равно 0, подпрограмма завершается, так как произведение — 0. Поскольку значения в регистрах H и L уже равны 0, подпрограмма может просто использовать команду JZ (Jump If Zero — перейти, если ноль), чтобы перейти к двум командам POP в конце программы.

В противном случае подпрограмма записывает в регистр B значение 0. Теперь в паре регистров BC содержится 16-битное множимое, а в аккумуляторе (А) — множитель. Команда DAD прибавляет значение BC (множимое) к значению HL (произведение). Значение множителя в A уменьшается на 1. Пока он не станет равен 0, выполнение команды JNZ (Jump If Not Zero — перейти, если не ноль) будет приводить к повторному сложению значения BC со значением HL. Этот небольшой цикл будет выполняться до тех пор, пока количество операций сложения BC и HL не станет равным множителю. (Более эффективную подпрограмму для умножения можно написать, используя команды сдвига из набора команд процессора 8080.)

Эту подпрограмму для перемножения чисел, например 25h и 12h, можно использовать в программе, добавив следующий фрагмент кода.

MVI B,25h

MVI C,12h

CALL Multiply

Команда CALL сохраняет в стеке значение счетчика команд, которое представляет адрес команды, следующей после CALL. Затем CALL вызывает переход к команде, на которую указывает метка Multiply. Это начало подпрограммы. После того как подпрограмма рассчитает произведение, она выполнит команду RET, в результате чего в счетчик команд будет возвращено значение из стека. Затем будет выполнена команда, следующая после CALL.

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

Код. Тайный язык информатики

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

Как микропроцессор взаимодействует с этими периферийными устройствами? (Все подключенные к микропроцессору компоненты, кроме памяти, называются периферийными.) Конструкция периферийных устройств, подобно памяти, предусматривает интерфейс. Микропроцессор может записывать и считывать данные с периферийного устройства, указывая определенные адреса, на которые оно реагирует. В некоторых микропроцессорах периферийные устройства фактически задействуют адреса, обычно используемые для обращения к памяти. Такая конфигурация называется вводом-выводом с распределением памяти. Тем не менее в процессоре 8080, кроме обычных 65 536 адресов для устройств ввода и вывода, специально зарезервированы 256 дополнительных, которые называются портами ввода/вывода. Адресные сигналы устройств ввода/вывода подаются на входы с A0 по A7, а от обращений к памяти их отличают сигналы, фиксируемые чипом системного контроллера 8228.

Вход
Поиск по сайту
Ищем:
Календарь
Навигация