Работа с ассемблером UniASM
В состав документации по программному обеспечению входит
руководство "UniASM.Руководство пользователя". В отличие от
руководств по Бейсику и Паскалю его авторы предполагают, что
читатель уже владеет программированием на ассемблере и это
руководство может быть использовано лишь как справочник для
квалифицированного программиста и совершенно бесполезно для
начинающих.
Данное пособие рассчитано именно на начинающих, поэтому
изложение содержания не предполагает каких-либо знаний по
ассемблеру.
Язык ассемблер является незаменимым в двух случаях:
-когда к программе предъявляются очень высокие требования по
быстродействию и она должна работать в условиях ограниченного
объема используемой памяти,
-когда необходимо использовать те возможности компьютера, которые
недоступны из языков высокого уровня.
Использование всех возможностей копьютера предполагает знание
его архитектуры. Эти сведения можно почерпнуть из книг [ ].
где дано описание микропроцессора 6800 фирмы Моторола. Этот
микропроцессор, объединенный с семейством других внешних устройств
с помощью системной шины, и образует компьютер Пълден. Структурная
схема ЦП М6800 показана на рис. 1.
А15 14 13 12 11 10 9 8 А7 6 5 4 3 2 1 0
---------------------- -----------------
| выходные буферы |-----------|выходные буферы|
---------------------- | -----------------
|-----|счетчик команд|
| H L
|-----|указатель стека|
| H L
SWI NMI IRQ RESET |-----|индексный регистр|
| | | | | H L
---------------------- |-----|аккумулятор А|
|Дешифратор команд и | |-----|аккумулятор В|
|система управления | |
| | |регистр признака результата|
|регистр команд|---------------| |
|-----| АЛУ |
|Буфер данных |---------------|
D7 6 5 4 3 2 1 0
Рис 1. Структурная схема МП6800
Пересылка данных между ЦП и периферийными устройствами
осуществляется по 8-разрядной шине данных (разряды обозначают
D0-D7). Для передачи адреса используется 16-разрядная шина адреса
( разряды А0-А15). Обе шины подключены к ЦП через трехстабильное
устройство для обеспечения возможности прямого доступа к памяти.
Адреса памяти и внешних устройств не различаются, поэтому
некоторые из 65К адресов являются общими для памяти и периферийных
устройств и различаются с помощью специальных разрядов в шине
управления. Таким образом все устройства ввода-вывода работают
в режиме распределенной памяти, поэтому для организации доступа
к портам ввода-вывода используется некоторая часть памяти. При
таком режиме работы УВВ необходимы дополнительные внешние
устройства типа адаптера сопряжения 6821, в котором имеются два
8-разрядных порта ввода-вывода, программируемые процессором для
работы в обоих направлениях, и синхронного адаптера последовательной
передачи данных типа 6852.
Общая структурная схема компьютера представлена на рис. 2.
В состав МП6800 входят арифметически-логическое
устройство (АЛУ), 16-разрядные счетчик команд (РС), указатель
стека, индексный регистр, два 8-разрядных аккумулятора А и В, и
регистр признака результата (регистр флагов или кодов условий CCR)
Указатель стека SP позволяет организовать стек в любом месте памяти,
системный стек обычно располагается в верхних адресах памяти.
Загрузка 16-ти разрядного указателя стека может быть произведена
командой LDS, что позволяет организовать несколько стеков. Стек
используется для запоминания содержимого счетчика команд PC
при обращении к подпрограммам, что дает неограниченную глубину
вложений.
Индексный регистр может быть использован для хранения данных или
16-разрядного адреса памяти при адресации с индексным регистром.
Регистр признака результатов хранит коды признака результата
операции АЛУ: отрицательный результат (N),нуль(Z), переполнение
(V),перенос из 7 разряда(C), полуперенос из 3-го разряда.
Значения этих разрядов используются в командах условного перехода.
Связь с внешними устройствами организуется с промощью системы
прерываний. В ЦП М6800 различаются 4 типа прерываний. Прерывание
является средством запроса со стороны периферийного устройства
на выполнение некоторого вида обработки данных в процессоре. В
системе управления имеется несколько выводов, предназначенных для
приема различных запросов на прерывание. Процессор при выполнении
каждой команды проверяет наличие запросов прерывания и при
обнаружении любого из них переходит к его обработке согласно схеме
рис. 3
------------------------
| |
| V
| Считывание команды
| |
| Выполнение команды
| / \ да
| есть ли прерывания?---->обработка
| \ / прерывания
| | нет |
|<-------------------------------------------
Рис. 3
При прерывании аппаратными средствами выполняется следующее:
1) устанавливается триггер разрешения прерывания
2)содержимое регистров ЦП заносится в стек
3)в программный счетчик помещается некоторый адрес.
Таким образом, следующая команда выполняется с нового адреса,
который содержит обычно начало программы обработки прерывания.
Прерывания делят на обычные (маскируемые) и намаскируемые.
Обычные прерывания обнспечивают запрет обработки других
прерываний до тех пор, пока не обработано текущее прерывание.
Триггер,используемый для управления режимами приема прерываний,
называется триггером разрешения прерывания. Программист может
сам сбрасывать и устанавливать этот триггер с помощью команд
SEI (разрешение прерывания) и DEI( запрет прерывания). Когда
принимается запрос прерывания, устанавливается бит маски
прерываний в регистре условных кодов, после чего процессор
переходит в состояние запрета прерываний,т.е. попросту игнорирует
следующие прерывания. Если в подпрограмме обработки прерываний
содержится команда SEI, то после нее возможен прием нового
прерывания. Обычно команда SEI помещается в конце подпрограммы.
Запрос немаскируемого прерывания происходит по выводу NMI и
не может быть запрещен, при этом ЦП всегда переходит к обработке
прерывания. При обнаружении запроса на обычное прерывание
процессор сначала выявляет установлена или нет маска прерывания
и при ее наличии переходит к выполнению следующей команды, не
выполняя действий по обслуживанию прерывания. Немаскируемые
прерывания обычно используются для сигнализации о неисправностях
в оборудовании, например, сбое питания. При возникновении
непредусмотренных ситуаций во время выполнения программы
происходят так называемые программные прерывания SWI. Эти
прерывания широко используются при обращении к подпрограммам,
помещенным в операционную систему, из пользовательских программ.
Эта команда может использоваться для обращения к какой-либо часто
вызываемой подпрограмме с целью экономии памяти. Адреса,
на которые происходит переход при обработке прерываний, называются
векторами прерываний. При обслуживании прерывания указываются
адреса соответствующих векторов (см. рис.4) и за ними следует адрес
вектора возврата.
Адрес Содежимое
FFF8 Обычное прерывание, IRQ
FFF9
FFFA Программное прерывание, SWI
FFFB
FFFC Немаскируемое прерывание, NMI
FFFE Сброс, RESET
FFFF
Рис. 4 Адреса векторов
Так как обычно в подпрограмме выполняется несколько операций,
то содержимое аккумуляторов и регистра кодов условий также должны
загружаться в стек. При использовании других регистров эта
процедура также обязательна. В процессоре М6800 загрузка
содержимого всех регистров в стек осуществляется автоматически.
Обработка прерывания происходит по схеме на рис .5
Обработка прерывания
/\ да
Маска прерывания =1 ?-------------
\/ |
|нет |
Пересылка в стек |
PC |
X |
A |
B |
CC |
| |
Установка триггера |
разрешения прерываний |
| |
Считывание вектора и |
помещение его в PC |
|---------------------------
V
Рис. 5 Обработка обычного прерывания
Для обеспечения быстрой реакции на прерывание с одновременным
запоминанием содержимого регистров PC,A,B еще до момента
поступления запроса аппаратного прерывания предназначена
команда WAI.
Система команд и способы адресации
Все операции, которые может выполнять процессор, представляются
в виде элементарных команд. При изучении команд необходимо дать
определение команды, показать чем она отличается от других
данных, хранимых в памяти, объяснить из каких частей она состоит
и как обозначается. Поскольку команды хранятся в оперативной
памяти, то они должны иметь двоичный вид и поэтому по внешнему
виду ничем не отличаются от данных, только процессор в состоянии
отличить является содержимое данного байта частью команды или
данным.
Большинство команд связано с передачей информации из одной части
системы в другую. А поскольку машина может обрабатывать информацию
только тогда, когда она доставлена в соответствующие регистры ЦП,
то многие передачи служат только для загрузки информации в нужное
место до ее обработки. Некоторые команды только определяют, где
находится следующая команда. Таким образом большинство команд
осуществляет пересылку или обработку данных, расположеннных в
памяти или регистрах.
Конструкция команды с определением назначения ее составных
частей ( групп бит) называется форматом команды. Команда обычно
состоит из двух частей. Первая часть команды сообщает о том, что
надо делать ( код операции), а вторая указывает, откуда должны
поступить данные для выполнения операций (адресат),т.е. часть
команды, определяющая выполняемое действие называется кодом
команды, а любой адрес или данные, необходимые для выполнения
команды называется операндом. Наиболее гибкая команда требует
до 4 операндов. Например, команда сложения должна указывать
адреса слагаемых, адрес результата и адрес следующей команды.
Так как для компьютера с емкостью памяти 64К для хранения
любого адреса необходимо 16 бит, то для записи такой команды
понадобится 9 байт памяти. Когда машина имеет 8 битовую шину
данных, то для считывания команды из памяти придется 9 раз
обратится к памяти. Таким образом, если при разработке системы
команд за главный критерий принять максимальную гибкость
команды, то получится медленнодействующая ЭВМ. Поэтому в
большинстве ЭВМ ограничились командами лишь с двумя операндами.
Это достигается следующими приемами:
1. Адрес следующей команды указывается только в командах
переходов, в остальных командах очередная команда выбирается из
ячеек памяти, следующих за выполненной командой (именно поэтому
и необходимы иногда команды перехода).
2. Для запоминания результата используется ячейка, в которой
находится один из операндов (аккумулятор).
3. Для сокращения числа бит, определяющих операнды, один или оба
операнда размещаются в регистрах ЦП, которые имеют короткие
адреса. Таким образм, при наличии двух операндов один из них
обычно изменяется и называется получателем (приемником,dst),
второй, который не изменяется, называется источником (src).
Например, при передаче источником называется тот операнд, откуда
берем данные, а при сложении -тот, содержимое которого складываем
с аккумулятором.Локализацию и обращение к операнду обеспечивают
так называемые способы (или режимы) адресации к данным.
Отчего возникла необходимость введения способов адресации? Для
8-разрядного процессора с памятью в 64К для указания любой из его
ячеек необходимо иметь длину адресной части равную 16 бит. Очевидно,
что команда длиной 8 бит не может включать в себя одновременно
код операции и 16-битную адресную часть. Значит большинство
команд имеет длину больше одного байта. Так как данные могут
храниться как в памяти, так и в регистрах, а длина адреса у них
разная, то компьютеру необходимо как-то сообщить какой адрес мы
ему сообщаем и как определить действительный адрес. Это и
осуществляется с помощью указания способа адресации. При введении
различных способов адресации в команде необходимо отвести биты,
указывающие режимы адресации для каждого операнда. Почти во всех
форматах команд первые биты отводятся для кода операции, остальные
биты должны определять операнды или их ячейки и поэтому они
используются для комбинаций режимов, адресов регистров, адресов
памяти, относительных адресов и непосредственных операндов.
Кодирование команд
Из вышеизложенного следует, что команды храняться в памяти в виде
двоичных чисел, ничем не отличаются от обыкновенных данных и
распознаются лишь по местоположению слова в памяти. Такая форма
представления команд называется машинным языком или машинным
кодом. Запомнить эти коды для человека сложно. Поэтому создатели
программного обеспечения предлагают набор мнемонических (алфавитно
цифровых) обозначений команд. Эти обозначения представляют собой
либо полное наименование выполняемой операции, либо ее 2-3-х
буквенное сокращение (аббревиатуру). Имя команды обычно является
активной формой соответствующего английского глагола (если слово
одно) или первые буквы нескольких слов (см.табл 1 )
Табл.1
Типичные команды и их мнемоническое обозначение
команда мнемоника
сложить add ad
вычесть substract sub
переслать move mov
загрузить load ld
сохранить store st
или or or
Группирование команд
Функционально все команды можно разбить в 5 основных групп:
1)пересылки данных, 2)управления, 3) обращения к подпрограммам,
4) операций, 5) ввода-вывода. Команды могут использовать данные
из памяти, регистров ЦП или просто управлять работой машины.
Рассмотрим функции отдельных команд.
Команды пересылки данных
К ним относятся команды пересылки данных из одной ячейки памяти
в другую, из регистра в регистр и в память и обратно. Команды
пересылки информации обозначают как move (переслать), load
(загрузить), store(записать), exchange (обменять). Работа со
стеком обеспечивается командами push(загрузить) и pull (извлечь).
Команды управления
делятся на условные и безусловные. Выполнение
условных команд зависит от содержимого регистра условных кодов.
Обычный набор команд этой группы включает следующие команды:
jump (переход)-по этой команде в счетчик команд PC заносится
адрес команды, которую необходимо выполнить следующей, branch
(ветвление)- переход по условию на другое место в программе.
Команды обращения к подпрограммам также могут быть условными и
безусловными. Типичными командами являются jump to subroutine
(переход на подпрограмму, мнемоника jsr)-безусловный переход по
указанному адресу и branch to subroutine (ветвление на подпрограмму
мнемоника bsr)-условный переход на подпрограмму.Возврат из
подпрограммы совершается по команде returns(возврат-мнемоника
rts).
Команды операций.
Сюда относится группа арифметических и
логических команд и команды операций над отдельными регистрами.
Примерами таких команд являются ADD (сложение),SUBSRACT (вычитание),
AND(и),OR(или),COMPARE(сравнение)-CMP, INCREMENT(увеличить на 1),
DECREMENT (уменьшить на 1)DEC, ROTATE (циклический сдвиг),
decimal adjust accumulator (произвести десятичную коррекцию
аккумулятора) DAA.
Команды ввода-вывода.
INPUT (ввод) в аккумулятор содержимого
порта ввода.OUTPUT(вывод) из аккумулятора в порт.
Конкретную кодировку команд и их работу мы рассмотрим при
обсуждении отдельных групп команд.
Способы адресации
Раннее мы выяснили, что команда должна содержать код операции,
признаки адресации и адрес(а) операнда(ов). Длина команды зависит
от выполняемой операции. Количество разрядов, отведенных для
каждой из этих составляющих команды, и их относительное расположение
в байтах определяется форматом команды. Признак адресации и адрес
операнда вместе определяют ячейку памяти или регистр, в которых
хранится операнд. Существуют несколько способов адресации операнда:
непосредственный, косвенный, относительный, с индексированием,
прямой. Признак адресации определяет способ вычисления адреса (его
интерпретации). Поясним схематично разные способы адресации:
1)Прямая адресация-в этом случае исполнитедльный адрес операнда
определен непосредственнно в команде. Например, операция сложить
содержимое ячейки памяти по адресу 032 с содержимым аккумулятора
записывается в виде ADD 032
Регистр команд Адрес память
Код операции|Прямая адресация|032 031
032 65-->операнд
2)Косвенная адресация-в команде указывается адрес, по которому
хранится адрес операнда
РЕгистр команд Адрес память
Код операции|Косвенная адресация|165 164
165 543
...
543 301-->операнд
При косвенной адресации возможно адресовать большой блок памяти
командой длиной в два байта. Часто используется разновидность
этого способа-косвенная адресация по регистру, когда адрес
операнда хранится в регистре ЦП.
3) Относительная адресация-исполнительный адрес определяется
относительно счетчика команд,т.е. для получения адреса операнда
указанное в команде значение складывается с содержимым счетчика
команд
Регистр команд
Код операции|Относительная адресация|11
Счетчик команд=124. Адрес операнда=124+11=135
4) Адресация с индексированием-похожа на относительную, но в
команде указывается адрес относительно содержимого некоторого
регистра, не являющегося счетчиком-индексного регистра.
Регистр команд
Код операции|Адресация с индексацией|32
Индексный регистр|341. Адрес операнда=341+32=373
Адресация с индексацией удобна в программах, где используются
таблицы или массивы данных. Адрес первого элемента таблицы
можно хранить в индексном регистре, а все остальные элементы
адресовать относительно первого.
5) Непосредственная адресация-данные задаются непосредственно в
команде. Загрузить в А число 7 -ldaa #7.
Операнд (7) содержится в самой команде и занимает 1 байт памяти,
следующий сразу за байтом команды.
Операции
Форматы команд
Операции над данными можно классифицировать по числу операндов.
Команды с одним операндом имеют следующий формат
Код операции операнд описание
ОР dst dst=F(dst)
dst от английского обозначает приемник,а src от англиского
sorce- источник являются символическими обозначениями на месте
которых могут стоять конкретные имена регистров или символы-метки.
Примером команд с одним операндом являются
inca,incb,inx,deca,decb,dex
которые приводят к увеличению и уменьшению на 1 содержимого
соответствующих регистров.Команды clra,clrb очищают регистры а и b.
Команда coma,comb производят инверсию значений отдельных разрядов
операнда,т.е. образуют дополнение до 1.Команды nega,negb путем
образования дополнения до 2 обеспечивает получение значения,
противоположного исходному-сначала производится инвертирование
значений отдельных разрядов ,а затем добавляется 1. Заметим, что
между мнемоникой операции и обозначением операнда отсутствует
пробел. К командам с одним операндом относятся также команды
работы со стеком psha,popa, помещающие значение аккумулятора в
стек и извлекающие его обратно из стека в аккумулятор.
Команды с двумя операндами имеют вид
Код операции операнд описание
ОРdst src dst=F(src,dst)
Реализация команд состоит в считывании величин операнда приемника
dst и операнда источника src, выполнении над ними операции и
записи результата в dst. Частным случаем этих команд являются
команды пересылки-состоящий в копировании величины src в dst.
Примерами таких команд являются
ldaa src, ldab src, ldx src, staa src, stab src, stx src,
где вид src зависит от способа адресации. Результатом выполнения
этих команд является копирование источника в соответствующий
регистр для операций ld и размещение содержимого регистра в памяти.
Команды сложения и вычитания
Основной арифметической операцией является двоичное сложение. При
арифметических операциях обычно считается, что байт содержит один
знаковый бит и 7 битов определяющих величину числа. Команды add и
sub не учитывают это различие. При совершении этих операций
компьютер отслеживает характер результата и устанавливает в
соответствии с ним разряды в регистре условных кодов. Эти разряды
затем используются в условных операторах для изменения хода
программы. Поэтому важно хорошо представлять как это происходит.
Рассмотрим это на простых примерах. Типичная операция
addst src
складывает два n-разрядных числа при нулевом начальном коде
переноса C=0, помещает сумму в dst и устанавливает разряды
условий. В табл. приведены примеры для 4-х разрядных чисел
Операция N Z V C Сложение чисел со знаком Сложение без знака
0100 0 0 0 0 +4 4
+0010 ++2 +2
------ ---- ----
0110 +6 6
0101 1 0 1 0 +5 5
+0111 ++7 +7
----- --- ----
1100 -4,переполнение 12
1101 0 1 0 1 -3 13
+0011 ++3 +3
----- --- ---
1|0000 0 0,перенос=1
1001 0 0 1 1 -7 9
+1100 +-4 +12
-------- ---- ---
1|0101 +5,переполнение 5,перенос=1
При операции вычитания операнд источника вычитается из операнда
приемника с использованием правил вычитания чисел в дополнительном
коде, т.е. сначала производится инвертирование значений отдельных
разрядов операнда src, а затем полученный результат при начальном
переносе равном 1 прибавляется к операнду dst. Разряд условия С
устанавливается в 1, если выполнение команды sub приводит к
возникновению заема. При использовании 4х разрядных чисел без
знака бит заема представляет собой дополнение бита переноса,
возникающего при соответствующем сложении.
9 1001 1-начальный перенос
- 5 -0101 1001
---- ----- +1010
4 0100,заема нет -----
1|0100 Перенос=1,сл-но заем=0
2 0010 1-начальный перенос
-13 -1101 0010
---- ----- +0010
5-16 0101,заем 1 -----
0|0101 Перенос=0,сл-но заем=1
7 0111 1-начальный перенос
- 7 -0111 0111
--- ----- +1000
0 0000,заема нет -----
1|0000 Перенос=1,сл-но заем=0
В таблице приведены примеры установки разрядов условий при
выполнении вычитания
Операция N Z V C Вычитание со знаком Вычитание без знака
0100 0 0 0 0 +4 4
-0010 -+2 -2
----- --- --
0010 +2 2
0101 1 0 0 1 +5 5
-0111 -+7 -7
------ --- --
1110 -2 14, заем=1
1101 0 1 0 0 -3 13
-1101 --3 -13
----- --- ---
0000 0 0
1001 0 0 1 0 -7 9
-0100 -+4 -4
----- --- --
0101 +5,переполнение 5
Вычитание используется для сравнения величин друг с другом, так
как Х<У тогда и только тогда, когда Х-У<0. Поэтому, если
SUBX Y приводит к отрицательному результату, то Х<У.
Для сравнения чисел используют команду CMP, которая обеспечивает
вычитание операндов и установку разрядов условий без изменения
операндов. Команда CMP устанавливает разряд С в 1, если при
вычитании возникает заем, а не перенос.
Команды ветвления
Команды условного перехода предназначены для проверки
определенного условия и осуществления перехода, реализуемого
только в том случае, если условие выполнено. Команды перехода,
в которых адрес перехода задается с использованием адресации
относительно счетчика команд, называются командами ветвления.
Команда содержит смещение в коде для получения адреса перехода
недалеко от текущей команды. Смещение интерпретируется как целое
число со знаком в дополнительном коде и в случае выполнения
условия перехода прибавляется к содержимому счетчика команд.
Обычно используются 15 стандартных условий перехода, приведенных
в таблице 2 . Пары BCC-BHS и BCS-BLO представляют собой
символические обозначения одних и тех же команд. С помощью
команд, приведенных в верхней части таблицы производится проверка
состояния отдельных разрядов условий. В средней части таблицы
даны команды, которые обеспечивают проверку величин целых чисел
со знаком. Если rr обозначает одно из состояний LT,GE,LE,GT,NE,EQ,
то X rr Y только тогда, когда X-Y rr 0. Например, так как
выполнение команды CMPX Y приводит к установке разрядов в
соответствии с разностью Х-У, то последовательность команд
CMPX Y
Brr LABEL
вызовет переход на метку Label только в том случае, если Х rr Y.
Таблица 2. Типичные команды условного перехода
Тип перехода Мнемоника Условие перехода
------------------------------------------------------------
Переход по BRA offset выполняется всегда
значению BCS offset установка разряда переноса С=1
отдельного BCC offset сброс разряда переноса С=0
разряда BVS offset установка разряда переполнения V=1
условия BVC offset сброс разряда переполнения V=0
BMI offset отрицательный результат N=1
BPL offset положительный результат N=0
BEQ offset равно нулю Z=1
BNE offset не равно нулю Z=0
-------------------------------------------------------------
Переход с BLT offset меньше нуля N XOR V=1
учетом знака BGE offset больше или равно нулю N XOR V=0
BLE offset меньше или равно нулю (N XORV) OR Z=1
BGT offset больше нуля (N XOR V) OR Z=1
----------------------------------------------------------------
Переход без BLO offset меньше С=1
учета знака BHS offset больше или равно С=0
BLS offset меньше или равно C OR Z=1
BHI offset больше C OR Z=0
Выражение N XOR V дает знак истинного результата, так как
равенство V=1 возможно только в том случае, если при вычитании
происходит переполнение, приводящее к неправильному знаку.
Команды перехода, приведенные в нижней части таблицы, используются
после операций сравнения целых чисел без знака, например адресов
памяти. Так как с помощью этих команд производится проверка
значения разряда С, то их следует применять только после команды
CMP. Выполнение команды CMPX Y приводит к вычитанию У из Х и
установке разряда С в 1, если при вычитании возникает заем. То
есть, когда Х и У интерпретируются как целые без знака, С
устанавливается в 1 тогда, когда Х меньше У. Команды BNE и BEQ
можно использовать как для чисел со знаком, так и без него,
так как в них производится поразрядное сравнение байтов.
Проверка установки указателей начала и конца очереди напротив
границы буфера выполняется с помощью команд условного перехода
без учета знака (BLS), так как начало и конец- это абсолютные
адреса и целые числа. Ошибочно использовать в такой ситуации
команду условного перехода с учетом знака.
Рассмотрим более подробно ситуации переполнения и переноса и
их использование в условных командах, так как здесь имеется
много сложностей.
Мы определили переполнение как ситуацию,когда абсолютная величина
результата просачивается в знаковый разряд. Но ситуация похожая
на переполнение иногда возникает, например, при сложении двух -1.
ldaa #$ff 11111111
adda #$ff +11111111
--------
1|1111110
Лишний разряд отбрасывается,остается число -2, представленнное в
дополнительном коде. Результат правилен и это не переполнение.
Рассмотрим еще один пример сложения 6 6
ldaa #$81 10000001 -2 +1+(-2 +1)
adda #$81 +10000001
--------
1|00000010 7
Отбрасывая левый бит, получаем число +2, а должно быть -2 +2.
Подобная ситуация называется переполнением не потому, что левый
разряд отбрасывается, а потому что арифметическая операция не
дает результата с правильным знаком. Итак, переполнение случается
тогда, когда знак результата арифметической операции неверен.
В случае переполнения устанавливается разряд V в 1. Арифметические
команды add,sub,cmp,neg,dec,inc, способные вызывать переполнение
очищают бит V, если оно не возникло. Команды ld,clr очищают бит V
всегда. Имеются команды перехода, реагирующие на состояние бита V.
Команда перехода BVS (Branch if V is Set-заглавные буквы образуют
мнемонику команды), если бит V=1 и команда перехода BVC, если бит
V=0. Допустим теперь, что нам нужно в программе организовать
условный переход в зависимости от результата сравнения содержимого
ячеек mem и wrd. Рассматривая их как обычные числа, которые могут
быть > и < 0, нам нужно перейти на метку lab, если (mem)>=(wrd).
Легко убедится, что фрагмент программы
ldaa mem
cmpa wrd
bpl lab
приведет к ошибке, если операция вычитания, осуществляемая
командой cmp дает переполнение. Так, если mem содержит 2,
а wrd содержит (-2 в шестой степени), то очевидно (mem)>(wrd),
однако команда cmpа wrd из-за переполнения сформирует результат
с 1 в 7-м бите и нулями во всех остальных. Команда BPL не
сможет распознать, что мы имеем ввиду операцию
6 6 7
2 -(-2 )= 2 ,
посколбку функция BPL ограничена проверкой бита N. В нашем случае
бит N равен 1, так как он устанавливается всегда, когда результат
вычислений имеет 1 в старшем разряде (это справедливо и для
логических команд). Итак cmp установит бит N и следовательно
команда BPL не приведет к ветвлению. Поэтому, когда в результате
выполнения команды CMP бит N равен 1, прежде чем осуществить
переход необходимо проверить, что 1 в левом разряде результата
есть следствие переполнения, а не признак отрицательного числа.
Иными словами, если оба бита N и V равны 1, то мы все же должны
осуществить переход
cmpa wrd
bpl lab
bvs lab
Так как команда bpl не изменяет условных признаков, то одной
команды cmp достаточно. Однако и это еще не гарантирует от ошибок,
так как мы не учли второй тип переполнения. Пусть mem содержит
число -2 в 7 степени, а wrd содержит 2 в 7 минус 1. Так как (mem)
отрицательно, а (wrd) положительно, то (mem)<(wrd) и поэтому
перехода не должно быть. Но вычитание выполняется так
10000000
-01111111
--------
00000001
Поскольку 7-й бит нулевой, то результат выглядит положительным и
ЦП сбросит бит N. Но арифметическая операция привела к результату
с неверным знаком:он должен быть отрицательным, так как
7 7 8
-2 - (2 -1)= -2 +1.
Поэтому ЦП установит бит V и эти команды вызовут переход. Таким
образом, если бит N нулевой, перед тем как делать переход надо
проверить, что 0 в 7-м бите результата говорит о переполнении, а
не о положительности полученного числа. То есть, когда бит N
нулевой, а бит V равен 1, нам не следует делать переход, т.е.
в общем мы должны осуществить переход, если одновременно оба
бита N и V либо 0, либо 1, и воздержаться от него, если один
из них 1, а другой 0. На языке логики это условие перехода
записывается в виде N OR V=0 и реализуется командой BGE,
переход, если больше или равно ( Branch if Greather than or
Equal).
Когда 1 переходит за левый край байта, говорят, что возникает
перенос, при этом бит С устанавливается в 1. Логические команды
и команда ld не влияет на С. Команда tst всегда сбрасывает C и
V. Команда add устанавливает бит С при переносе, иначе сбрасывает
его. Команды sub и cmp устанавливают С, когда при вычитании
необходим перенос единицы в левый бит байта, иначе сбрасывают его.
Рассмотрим пример вычитания 5-7
00000101
-00000111
--------
11111110
получаем представление -2 в дополнительном коде. Устанавливается
бит С. С арифметической точки результат корректен и поэтому бит
V сбрасывается.
Имеются команды, реагирующие на состояние бита С: команда BCS
перехода, если бит С установлен (Branch if C Set) и команда BCC
(Branch if C is Clear). Допустим нужно обнулить блок памяти, на
начало которого указывает mem , на конец- содержимое регистра Х.
Запишем фрагмент программы так
loop clr mem
inc mem
cpx mem
bpl loop
Если 15-й разряд равен 1, то будет установлен бит N и команда
BPL не приведет к переходу. Еще раз предостерегаем от неявного
допущения, что процессор знает, с каким типом данных он работает
( как в данном случае- что он работает с адресами, а не с обычными
числами со знаком). Фрагмент программы должен быть такой
loop clr mem
inc mem
cpx mem
bcc loop
Логические операции
Логические операции обеспечивают обработку байта как массива
битов, причем каждый бит обрабатывается независимо от других.
О результатах выполнения различных логических операций дает
представление обобщенная таблица истинности
src,x dst,y NOT X X AND Y X OR Y X XOR Y X BIC Y
0 0 1 0 0 0 0
0 1 1 0 1 1 1
1 0 0 0 1 1 0
1 1 0 1 1 0 0
X BIC Y=(NOT X)AND Y приводит к сбросу в dst тех разрядов,
которым в src соответствуют 1.
Логические операции чаще всего используются для извлечения и
объединения полей разных данных.Для этого используются так
называемые маски-констаны, в полях которых, соответствующих
полям, подлежащим извлечению, находятся единицы, а в остальных
полях нули. При выполнении логических операций разряды N и Z
устанавливаются в соответствии с полученным результатом, V
сбрасывается, С сохраняется. Для проверки поля байта с
использованием маски без записи результата используют команду
BIT поразрядной проверки разрядов. Команда проверки битов BIT
(BIt Test) осуществляет логическую функцию AND над своими
операндами. Так, например, bita #$04 формирует байт (а)and $04,
т.е. байт, в котором бит равен 1 в том и только в том случае,
если в обоих операндах соответствующие биты равны 1. Команда
BIT формирует результат в недоступном внутреннем регистре, не
изменяя содержимое операндов. Условные признаки устанавливаются
в соответствии со значением результата, т.е. команда BIT
является логическим аналогом команды CMP. Допустим (а)=$04,
тогда получим
а 00000100 and
маска 00000100
результат ---------
00000100
таким образом будет установлено Z=0,N=0. Z=1 будет установлен
только в том случае, когда числа не совпадают.
Исключающее или (EOR). Например, после выполнения команды
ldaa #$20
eora #$FF
будет сделано
а 00100000
маска 11111111
результат 11011111
приводит с сбросу 5-го бита аккумулятора и установке остальных
битов в 1.
Включающее или (OR) для того же примера даст следующий результат
ldaa #$20
ora #$FF
a 00100000
маска 11111111
результат11111111
Циклические, логические и арифметические сдвиги
Операции циклического, логического и арифметического сдвигов
производятся над содержимым одного слова, сдвигаются биты этого
слова на одну позицию вправо или влево. Термин циклический сдвиг
обычно используется для таких операций, при выполнении которых
не происходит потери битов.
RL dst циклический сдвиг влево
RR dst циклический сдвиг вправо
RLC dst циклический сдвиг влево с использованием разряда С
RRC dst циклический сдвиг вправо с использованием разряда С
Разряды N и Z устанавливаются обычным образом. Циклический сдвиг
с повышенной точностью можно программировать, используя разряд
С как звено связи.
Логическим сдвигом называется операции сдвига, при которых в
освободившемся разряде устанавливается 0. Выталкиваемый бит
сохраняется в С, а старое значение С теряется.
SLL dst логический сдвиг влево
SRL dst догический сдвиг вправо.
При арифметических сдвигах операнды обрабатываются как числа со
знаком, представленные в дополнительном коде. Сдвиг влево
эквивалентен умножению на 2, вправо- делению на 2.
SLA dst арифметический сдвиг влево
SRA dst арифметический сдвиг вправо
Заметим, что команды SLL и SLA эквивалентен.
Для адресации и работы с отдельными разрядами слова используют
стандартные команды логических операций и маски с одной единицей
или одним нулем. Например, с помощью команд
AND dst,#$7FFF
OR dst,#$8000
XOR dst,#$8000
BIT dst,#$8000
производят соответственно, сброс, установку, инвертирование и
проверку старшего разряда 16-битного слова dst.
Правила записи текста программы на ассемблере
Текст программы (на жаргоне программистов называемый "исходником")
обычно создается с помощью текстового редактора. Чтобы ассемблер
мог его странслировать, он должен быть написан по определенным
правилам. Текст программы пишется в виде строк, длина которых не
может превышать 255 символов (обычно она равна 40 символам). В
одной строке может быть записана только одна инструкция. Строка,
в которой в первой позиции стоит ";" считается комментарием и не
транслируется. Каждая строка может содержать до четырех полей:
[метка] <операция> {операнд} [комментарий]
Квадратные скобки использованы для указания, что эти поля могут
отсутствовать в строке. Знаки "{,[,<" в тексте не указываются и
использованы здесь только для обозначения полей. Соседние поля
отделяются одним или более пробелами. Строчные и прописные буквы
различаются только в случае строки символов.
Определим основные синтаксические категории, с помощью которых
описываются правила.
Символом называется определенное в программе имя, значением
которого является целое 16-чное число без знака. Символ
определяется меткой или директивой "=". Символ должен начинаться
латинской буквой и может включать буквы, цифры и "_". Длина,
которая учитывается, равна 8 символам. Число определенных
объектов не может быть более 2048.
Константы разрешены десятичные, 16-чные (для их указания
используется знак $), двоичные (знак %), графические (заключается
в апострофы и получает значение кода ASCII), два графических
символа в апострофах определяют константу длиной в два байта
с кодами ASCII символов.
Выражением называется последовательность символов и/или
констант, и/или символа '.'- текущего значения счетчика адреса,
связанные знаками операций. Знаки "<" и ">" перед выражением
определяют какой байт выражения будет считаться результатом-
старший или младший. Допустимы операции -+*/&!. Выражение
может содержать один неопределенный символ, который будет
определен позже.
Списком выражений называется последовательность выражений,
разделенных запятыми.
Символы, констаны и выражения кроме значения характеризуются
еще и типом: относительным или абсолютным. Абсолютныым типом
является фиксированные адреса памяти или числа. Относительным
типом является неопределенный во время трансляции адрес.
Тип символов определяется по следующим правилам:
1. Если символ определен знаком =, то тип его определяется
типом выражения справа от знака.
2. Символы метки имеют относительный тип.
3. Символ текущего значения счетчика относителен.
Тип выражения определяется типом операции и ее операндов по
определенным правилам.
Если первый символ строки не является пробелом, табуляцией или
";", то первое поле каждой строки- поле метки, т.е. метки всегда
должна начинаться с первой позиции. Строка может иметь только
одну метку. Метка рассматривается как символ программы, значение
которого равно текущему значению счетчика адресов. Метка является
адресом следующей за ней инструкции.
Поле операции следует за меткой, если метка отсутствует, то
перед ним должен быть хотя бы один пробел. Поле может содержать
мнемонику машинной команды или инструкции. В поле может быть
записана команда int $** вызова специальной функции операционной
системы.
Поле операнда определяется операцией и указывает объект действия
команды. Если команда содержит два операнда, то первый операнд
записывается как часть мнемоники команды, например, ldaa #6-
загрузить в аккумулятор А(первый операнд) число 6 (второй операнд)
В качестве операнда разрешены: адрес, вычисляемое выражение и
строка символов.
В поле комментария первый символ должен быть ";"
Кроме обычных команд в строках могут быть использованы так
называемые директивы транслятору, которые не транслируются им, а
используются для управления транслятором. Наиболее часто
используемыми из них являются директивы определения данных,
которые предназначены для резервирования в памяти машины места
для данных и указания типа ( и возможно значения) данных, которые
будут размещены в этом месте.
db < список выражений>
записывает в объектном коде последовательность байтов, каждый из
которых является значением очередного выражения. Каждое выражение
должно быть абсолютного типа и находится в интервале [0,255].
dw <список выражений>
записывает в объектном коде последовательность слов (двухбайтных
значений) в порядке (старший байт, младший байт), каждое из
которых является значением очередного выражения.
ds <выражение>[,<список выражений>]
записывает в объектном коде последовательность байтов, каждый из
которых является значением очередного выражения. Значение
выражения определяет сколько раз будет записана последовательность
байтов. Если список выражений пропущен, в объектном коде
пропускаются байты, число которых определено значением выражения.
При трансляции программы может быть директивой указан режим
выдачи листинга трансляции с помощью директивы
LIST <выражение>,
которая включает/прекращает создание листинга,значение выражения
0 определяет вывод, не 0-прекращение.
При этом на каждой строке листинга выдается
адрес строки, машинный код по этому адресу, номер соответствующей
строки исходного файла, содержание исходной строки.
В конце листинга выводится таблица определенных символов и их
значений. Не примененные символы обозначаются "?".
Директива PAGE определяет переход на новую страницу.
Определение символа совершается с помощью директивы
< символ> =< выражение>
Директива CMD, которая должна стоять первой в тексте программы,
задает тип выходного файла. Если она пропущена, то генерируется
файл типа .OBJ.
Директива ORG <выражение> присваивает значение счетчику адресов
и используется для позиционирования программы на определенный
начальный адрес.
Директива SECT [выражение] формирует фиктивную секцию,
начинающуюся с адреса значения выражения.
Директива ENDS отмечает конец секции.