Аналитический обзор книги Программирование на языке ассемблера для микропроцессоров 8080 и 8085
Аналитический обзор книги Программирование на языке ассемблера для микропроцессоров 8080 и 8085
ВВЕДЕНИЕ
Интенсивное развитие микроэлектроники и повышения степени интеграции
открыли новое направление в ВТ - создание микропроцессоров и
микрокомпьютеров. Появились вы числительные системы с малым уровнем
потребления энергии и универсальными возможностями, которые позволяют
решать задачи управления объектами различной физической природы. На основе
их применения снижаются затраты на автоматизацию основных технических и
вспомогательных процессов. В результате будет решена задача комплексной
автоматизации производства во всех отраслях. Это позволит увеличить
производительность труда, уменьшить себестоимость выпускаемой продукции и
значительно сократить ручные операции в промышленности. Однако для широкого
развития работ в данном направлении необходимо готовить значительное число
инженеров - системотехников, умеющих создавать и применять микропроцессоры
и микрокомпьютеры. Кроме того, следует выпускать и много инженеров -
математиков, разрабатывающих соответствующее программное обеспечение. Для
их обучения необходимо иметь учебные пособия, посвященные аппаратным и
программным средствам современной вычислительной техники.
Несмотря на то что выпущено значительное количество литературы,
посвященной разработке и применению микропроцессоров и микрокомпьютеров, а
также описание программных средств, предлагаемая книга представляет
определенный интерес комплексным подходом и методической целостностью.
На обзор представлена книга американских авторов Левенталя Л. и Сэйвилла У.
"Программирование на языке ассемблер для микропроцессоров 8080 и 8085".
Книга переведена с английского, напечатана в 1987г. в издательстве Радио и
связь. Издание включает в себя 488 страниц.
Для начала рассмотрим содержание этой книги чтобы сделать окончательный
анализ по ее достоинствам и недостаткам, а также конкретизировать к какой
группе эта книга предназначена. На обзор кратко будут представлены части
этой книги, затем остановим свое внимание на определенной главе.
Книга состоит из двух частей: обзора вопросов программирования на языке
ассемблера и набора подпрограмм. Первая часть хорошо проиллюстрирована
большим числом примеров, позволяющих быстро усвоить основные навыки
программирования для рассматриваемых микропроцессоров. Подпрограммы,
приведенные во второй части книги, могут удовлетворять потребности
большинства программистов в стандартных процедурах.
Эта книга, можно сказать, является как бы справочным пособием для
программистов, работающих на языке ассемблера. Она содержит краткий обзор
вопросов программирования на языке ассемблера для конкретного
микропроцессора и набор полезных подпрограмм. В этих подпрограммах
использовались стандартные соглашения по формату, документированному
оформлению и методам передачи параметров. При этом соблюдались правила
наиболее распространенных ассемблеров; кроме того, описаны назначение,
процедура, параметры, результаты, время выполнения и требования к памяти.
ГЛАВА 1. ОБЩИЕ МЕТОДЫ ПРОГРАММИРОВАНИЯ
Служит введением в программирование для данного процессора; в ней
приводятся основные отличия этого процессора от других микропроцессоров и
мини-ЭВМ. В этой главе описываются общие методы написания программ на языке
ассемблера для микропроцессора 8080 и 8085. Она содержит способы выполнения
следующих операций:
загрузка и сохранение регистров;
запоминание данных в памяти;
арифметические и логические операции;
работа с разрядами;
проверка разрядов;
проверка на определенные значения;
числовые сравнения;
организация циклов (повторяющихся последовательностей операций);
обработка массивов;
поиск в таблице;
работа с символами;
преобразование кодов;
арифметические операции повышенной точности;
умножение и деление;
обработка списков;
обработка структур данных.
В отдельных разделах описываются передача параметров подпрограммам,
общие методы написания драйверов ввода-вывода и программ обработки
прерываний, а также приемы, позволяющие ускорить выполнение программ и
уменьшить используемую ими память.
Для тех, кто знаком с программированием на языке ассемблера на других
вычислительных машинах, здесь дается краткий обзор особенностей процессоров
8080 и 8085.
1. Арифметические и логические операции разрешены только между
аккумулятором и байтом непосредственных данных или между аккумулятором
и регистром общего назначения. Однако один регистр общего назначения в
действительности указывает на адрес в памяти; это регистр М, который в
действительности обращается к адресу в памяти, содержащемуся в
регистрах Н и L. Таким образом, команда ADD M, например, означает:
прибавить к аккумулятору содержимое байта памяти, адресуемого через
регистры H и L.
2. Аккумулятор и регистры Н и L являются специальными регистрами. Они
являются единственными регистрами , которые могут быть прямо загружены
или записаны в память. Аккумулятор является единственным регистром,
который может быть инвертирован, сдвинут, косвенно загружен с
использованием адреса в паре регистров В или D, косвенно записан в
память по адресу, содержащемуся в паре регистров В или D, или
использован в командах IN и ОUT. Регистры Н и L составляют единственную
пару, которая может быть использована косвенно в арифметических
командах, при записи в память данных, заданных непосредственно в
команде, или при загрузке и записи в память других регистров, отличных
от аккумулятора. Регистры Н и L являются также единственной парой,
которая может быть передана в счетчик команд или указатель стека. Более
того, эти регистры используются как аккумулятор двойной длины при
сложении 16-разрядных чисел (команда DAD). Регистры D и Е являются в
некотором смысле также специальными, поскольку одной командой (XCHG)
можно поменять их содержимое с содержимым регистров Н и L. Таким
образом, регистры в 8080 и 8085 весьма асимметричны, и программист
должен аккуратно выбирать, для каких данных и адресов какими регистрами
пользоваться.
3. Часто для одних и тех же физических регистров используются несколько
имен. Для многих команд A,B,C,D,E,H и L являются 8-разрядными
регистрами. Для других команд регистры В и С (В- старший по значению),
D и Е (D- старший по значению) или Н и L (Н- старший по значению)
являются 16-разрядной парой регистров. Термины пара регистров В,
регистры В и С и пара регистров ВС имеют одно и тоже значение; подобные
же варианты существуют для регистров D и Е и H и L. Заметим, что пара
регистров и два одиночных регистра физически одно и то же, и они не
могут служить одновременно для различных целей. Регистры Н и L
фактически почти всегда применяют для косвенного адреса из-за наличия
команд, имеющих доступ к регистру М, и таких специальных команд, как
SPHL, PCHL, XTHL и XTHG. Благодаря тому, что существует команда XCHG,
для второго адреса берут регистры D и Е , а не В и С. Регистры В и С
используют обычно как отдельные 8-разрядные регистры для временного
хранения данных.
4. Воздействие различных команд на флаги весьма непоследовательно. К
некоторым особенно необычным действиям относятся следующие:
e) логические команды очищают флаг переноса;
f) команды сдвига не действуют на другие флаги, кроме флага переноса;
g) команды загрузки, записи, пересылки, увеличивают на 1 пары регистров
и уменьшают на 1 пары регистров вообще не оказывают влияния на флаги;
h) 16-разрядное сложение действует только на флаг переноса.
9. Отсутствует косвенная адресация через память и индексация. Отсутствие
косвенной адресации через память компенсируется загрузкой косвенного
адреса в регистры Н и L. Действительная косвенная адресация, таким
образом, является двухшаговым процессом. При желании загрузить или
записать в память аккумулятор можно также загрузить косвенный адрес в
регистры В и С или D и Е. Отсутствие индексной адресации компенсируется
добавлением пары регистров с помощью команды DAD. Эта команда добавляет
пару регистров к Н и L. Таким образом, индексация требует нескольких
шагов:
j) загрузить индекс в пару регистров,
k) загрузить базовый адрес в другую пару (одной из пар регистров должны
быть Н и L), в) используя команду DAD, сложить две пары и г)
использовать сумму как косвенный адрес (при помощи обращения к
регистру М). Индексация в 8080 и 8085 - долгий и неудобный процесс.
12. Нет флага переполнения при получении дополнения до двух, так что надо
определять такое переполнение программным путем. Из этого следует, что
трудно работать с числами со знаком.
13. Многие обычные команды отсутствуют, но могут быть легко смоделированы с
помощью регистровых команд. Примерами являются очистка аккумулятора ( с
использованием SUB A или XRA A), логический сдвиг аккумулятора влево
(с помощью ADD A), очистка флага переноса (ANA A или ORA A) и проверка
аккумулятора (ANA A или ORA A). Команда ANA A и ORA A очищают флаг
переноса и устанавливают остальные флаги в соответствии с содержимым
аккумулятора. Причем загрузка регистра не действует на флаги.
14. Нет относительных переходов. Фактически, единственной командой
перехода, которая не требует абсолютного адреса, является PCHL, по
которой загружается счетчик команд из регистров Н и L и, таким образом,
производится косвенный переход.
15. Есть два отдельных набора команд увеличения и уменьшения на 1. Команды
DCR и INR применяются к 8-разрядным регистрам и действуют на все флаги,
за исключением флага переноса. Команды DCX и INX применяются к 16-
различным парам регистров и вообще не действуют на флаги. Можно
использовать 16-разрядные пары регистров как обыкновенные счетчики, но
единственным способом проверки пары на 0 является использование команды
логическое ИЛИ к двум регистрам вместе с аккумулятором.
16. Нет арифметических или логических сдвигов. Единственными командами
сдвига являются команды циклического сдвига с флагом переноса или без
него. Другие сдвиги могут быть смоделированы при помощи команд
циклического сдвига (RRC, RLC, RAR и RAL) и команд сложения (ADD A, ADC
A и DAD H). Флаг переноса может быть установлен с помощью STC, а очищен
с помощью ANA A (или ORA A).
17. Аккумулятор является единственным регистром, который может быть
сдвинут, инвертирован или использован для ввода или вывода.
Единственными командами, которые оперируют непосредственно с регистрами
общего назначения, являются команды MOV ( пересылка содержимого в
другой регистр или из другого регистра), MVI (загрузка
непосредственного операнда), DCR (уменьшает на 1) и INR (увеличение на
1). Эти команды могут оперировать также с регистром М, т.е. байтом из
памяти, адресуемым через регистры Н и L.
18. В стек или из стека могут быть переданы только пары регистров. Одной из
таких пар является слово состояния процессора (PSW), которое содержит
аккумулятор (старший байт) и флаги (младший байт). Команды CALL и
RETURN передают адреса в стек или из него.
19. В микропроцессоре 8080 отсутствует читаемый флаг системы прерываний.
Это создает трудности в том случае, когда исходное состояние системы
прерываний должно быть восстановлено после выполнения секции команд,
которая должна выполняться при закрытых прерываниях. Для решения этой
проблемы можно копию состояния прерываний хранить в ОЗУ. С другой
стороны, 8085 имеет читаемый флаг разрешения прерываний.
20. В микропроцессорах 8080 и 8085 приняты следующие общие соглашения.
. При записи всех 16-разрядных адресов младший байт записывается
первым (т.е. по меньшему адресу). Порядок байтов в адресах тот же,
что и в микропроцессоре Z80 и 6502, но является обратным порядком
байтов, принятому в микропроцессорах 6800 и 6809.
. Указатель стека содержит младший адрес, действительно занятый в
стеке. Это соглашение также принято в микропроцессорах Z80 и 6809,
но явно противоположно принятому 6502 и 6800 (следующий доступный
адрес). Согласно всем командам 8080 и 8085 данные в стек
записываются с предварительным уменьшением на 1 (вычитанием перед
записью байта 1 из указателя стека) и загружаются из стека с
последующим увеличением на 1 (добавлением после загрузки байта 1 к
указателю стека).
. Флаг разрешения прерываний (только в 8085), равный 1, разрешает
прерывания, а 0 - запрещает их. Такое же соглашение принято и в
Z80, но оно обратно принятому в 6502, 6800 и 6809.
Представленная часть первой главы рассмотрела особенности процессоров,
она так и называется - краткий обзор для опытных программистов. Теперь
будем рассматривать дальше, причем не указывая конкретно команды, а
описывая понятия и особенности операций представленной на обзор первой
главы данной книги.
ЗАГРУЗКА РЕГИСТРОВ ИЗ ПАМЯТИ
В микропроцессорах 8080 и 8085 предусмотрены четыре способа адресации,
которыми можно пользоваться при загрузке регистров из памяти: прямая (из
памяти с конкретным адресом), непосредственная (с конкретным значением),
косвенная (из адреса, помещенного в паре регистров) и стековая ( из
вершины стека).
ЗАПОМИНАНИЕ РЕГИСТРОВ В ПАМЯТИ
Для запоминания регистров в памяти существуют три способа адресации:
прямая (в память с конкретным адресом), косвенная (в память с адресом,
который находится в паре регистров) и стековая (в вершину стека).
ЗАПОМИНАНИЕ ДАННЫХ В ОЗУ
Начальные значения ячеек ОЗУ задаются либо через аккумулятор, либо
прямо или косвенно с использованием регистров Н и L.
АРИФМЕТИЧЕСКИЕ И ЛОГИЧЕСКИЕ ОПЕРАЦИИ
Для большинства арифметических и логических операций (сложение,
вычитание, логическое И, логическое ИЛИ, ИСКЛЮЧАЮЩЕЕ ИЛИ и сравнение) одним
из операндов является аккумулятор, а вторым 8-разрядный регистр или байт
данных, заданный непосредственно в команде. Результат (если он существует)
помещается в аккумулятор. Если используется регистр М, то процессор
получает операнд из памяти по адресу, который содержится в регистрах Н и L.
РАБОТА С РАЗРЯДАМИ
Программист может установить, очистить, получить обратный код
(дополнение к 1) или проверить разряды, используя логические операции с
соответствующими масками. Команды сдвига и получение обратного кода могут
оперировать только с аккумулятором, но в то же время для выполнения
небольшого числа сдвигов могут использоваться арифметические и логические
команды. Возможны следующие операции с отдельными разрядами аккумулятора:
установить с помощью операции логическое ИЛИ с единицами в соответствующих
позициях;
очистить с помощью операции логическое И с нулями в соответствующих
позициях;
инвертировать (изменить на обратное значение) с помощью операции
ИСКЛЮЧАЮЩЕЕ ИЛИ с единицами в соответствующих позициях;
проверить (на все нули в проверяемых разрядах) с помощью операции
логическое И с единицами в соответствующих позициях.
ПРИНЯТИЕ РЕШЕНИЙ
Процедуры принятия решений могут быть классифицированы следующим
образом
переход, если разряд установлен (логическая единица) или очищен (логический
нуль);
переход, если два значения равны или не равны;
переход, если одно значение больше другого или меньше его.
Наличие процедур первого класса позволяет процессору реагировать на
значения флагов, переключателей, линии состояния или других двоичных
(включено- выключено) сигналов. Наличие процедур второго класса позволяет
процессору определить, имеет ли вводимая величина или результат
определенное значение (например, введен ли определенный символ команды или
терминатор, или равен ли результат нулю). Наличие процедур третьего класса
позволяет процессору определить, превышает ли значение некоторый числовой
порог или ниже его (например, правильное или ошибочное значение, выше или
ниже предупредительного уровня или заданной точки).
ОРГАНИЗАЦИЯ ЦИКЛОВ
Самый простой способ выполнения цикла (т.е. повторения
последовательности команд) в микропроцессоре 8080 или 8085 состоит в
следующем:
1. Загрузить в регистр общего назначения число, указывающее, сколько раз
должна быть выполнена последовательность команд:
2. Выполнить команды;
3. уменьшить заданный регистр на 1;
4. вернуться к шагу 2, если результат шага 3 не равен 0.