Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка по практике ЭВМ и ПУ.doc
Скачиваний:
2
Добавлен:
01.07.2025
Размер:
12 Мб
Скачать
☆

8.2 Способы адресаций.

В МПК КР580 используется три способа адресации: прямой, непосредственный и косвенный.

При прямой адресации, адресом операнда является адрес регистра микропроцессора, который указывается в байте кода операции. Регистры имеют следующие адреса:

В – 000; С – 001; D – 010; Е – 011; Н – 100; L – 101; М – 110; А – 111.

Под регистром М понимается ячейка памяти, адресом которой служит содержимое пары регистров HL.

Приведем пример команды из языка Assembler для МПК КР580, который более подробно будет рассмотрен ниже. Команда представлена в двоичном коде 01 001 010.

В данной команде 01 – это код операции. Этот код показывает, что это команда пересылки данных из регистра в регистр.

Следующие две триады показывают коды регистров, между которыми ведется пересылка. Сначала пишется код регистра, в который пересылаются данные, а затем и которого они считываются. 001 – это регистр С, а код 010 – регистр D. Значит, пересылка ведется из регистра D в регистр С. Мнемоника этой команды будет иметь вид: MOV C, D.

Другая команда 10 000 010. Старшие пять разрядов (10000) – это код операции, т. е. суммирование. В трех младших разрядах указывается код регистра, в котором находиться один из операндов. В нашей команде это регистр D (010). Другой обязательно должен быть в аккумуляторе, поэтому в команде он не указывается. Результат всегда записывается в аккумулятор, поэтому так же в команде не указывается. Мнемоника этой команды ADD D.

При непосредственной адресации операнд задается непосредственно в команде во втором или втором и третьем байтах.

Например, команда ADI предусматривает суммирование содержимого аккумулятора с числом из второго байта команды. Для какого-то определенного случая команда будет иметь вид: ADI 4C. Команда двухбайтная. Первый байт – это код команды. Значит, во втором байте находиться операнд, с которым будет складываться содержимое аккумулятора. В данном случае – этот операнд равен 4С.

Команда LXI производит загрузку операндов, приведенных во втором и третьем байтах в пару регистров, например DE. Тогда команда будет иметь вид: LXI D.

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

При косвенной адресации в команде отмечается пара регистров РОН, содержимое которых служит адресом, по которому в оперативной памяти находиться операнд.

Так команда LDAX загружает в аккумулятор содержимое ячейки памяти, адресом которой служит содержимое пары регистров. Например, LDAX В, обозначает, что в паре регистров BC находиться адрес ячейки памяти, в которой храниться операнд, необходимый для загрузки в аккумулятор.

Для рассмотрения принципа составления программ для процессора необходимо знать систему команд. В таблице 1 приведена система команд для МПК КР580.

8.3 Составление линейных программ на языке Assembler.

Язык программирования Assembler является языком низкоуровневого программирования. Он позволяет писать программы, на основе которых работает МПК, процессоры и контроллеры. Все устройства МПК работают на основе последовательности команд. Эта последовательность называется программой. Для составления программ необходима система команд, т. е. совокупность всех команд, на основе которых работает МПК. Для каждого МПК система команд своя, т. к. каждый МПК может отличаться разрядностью, составом, возможностями и т. д.

Особенностью линейных программ является отсутствие условий и циклов. Каждая команда программы выполняется последовательно друг за другом.

Рассмотрим принцип построения линейных программ на конкретном примере.

Принять из ОЗУ два числа, хранящихся в соседних ячейках памяти с адресами 0276(16) и 0277(16), и вычислив сумму этих чисел, поместить ее в ОЗУ на место второго числа.

Решение.

Так как оба числа находятся в памяти, т. е. С точки зрения процессора в регистре М, то что бы он стал доступен, необходимо поместить адрес ячейки памяти в пару регистров HL. Эта операция описывается следующим образом: .

При сложении двух чисел одного из них обязательно должно быть помещено в аккумулятор. После того, как в регистры HL был помещен адрес 0276, стала доступна соответствующая ячейка памяти (регистр М). Тогда

можно число из этой ячейки памяти переместить в аккумулятор. Данная операция может быть описана следующим образом: . Здесь необходимо обратить внимание на скобки, в которые заключен регистр М. Это обозначает, что необходимо взять содержимое регистра М. Если эти скобки опустить, то получиться, что необходимо переместить сам регистр. Таким образом, данная запись читается: в регистр А переместить содержимое регистра М. Если скобок не будет, то читаться будет так: в регистр А переместить регистр М. А это не правильно. Поэтому, отсутствие скобок будет считается грубой ошибкой в программе.

Таблица 1

Мнемоника

Структура команды

Количество байт

Операция

Команды пересылки

MOV ri rj

01 ri rj

1

Регистр-регистр ri <-(rj)

MVI ri

00 ri 110

2

Непосредственная загрузка регистра

ri <- <B2>

LXI ri

00 ri 001

3

Непосредственная загрузка пары регистров

ri <- <B3> ri+1 <- <B2>

00К1010

STAX B

000

1

Содержимое аккумулятора загрузить в ЯП адрес которой записан в регистрах В и С

[(BC)] <-(A)

STAX D

010

1

[(DE)] <-(A)

LDAX B

001

1

(A) <-[(BC)]

LDAX D

011

1

(A) <-[(DE)]

STA

110

3

Содержимое аккумулятора загрузить в ЯП адрес которой записан в во втором и третьем байтах команды [<B3B2>] <-(A)

LDA

111

3

(A) <- [<B3B2>]

SHLD

100

3

[<B3B2>] <-(L); [<B3B2> + 1] <-(H)

LHLD

101

3

(L) <- [<B3B2>]; (H) <- [<B3B2>]

SPHL

11111001

1

SP <-(HL)

PCHL

11101001

1

PC <-(HL)

Команды приращения

INR ri

00ri100

1

Содержимое регистра увеличить на 1

ri <-(ri) + 1

DCR ri

00 ri101

1

ri <-(ri) - 1

INX ri

00ri011

1

Содержимое пары регистров увеличить на единицу riri+1 <- ( riri+1) +1

DLX ri

00ri011

ri-1ri <-( ri-1ri) - 1

Арифметические операции

10К2ri

ADD ri

000

1

Содержимое аккумулятора сложить с содержимым регистра. Результат записать в аккумулятор A <- (A) + (ri)

ADC ri

001

1

То же, но к сумме прибавить содержимое триггера переноса A <- (A) + (ri) + (Tc)

Продолжение таблицы 1

Мнемоника

Структура команды

Количество байт

Операция

SUB ri

010

1

A <- (A) - (ri)

SBB ri

011

1

A <- (A) - (ri) - (Tc)

ANA ri

100

1

A <- (A) Λ (ri)

XRA ri

101

1

A <- (A) mod2 (ri)

ORA ri

110

1

A <- (A) v (ri)

CMR ri

111

1

Сравнение содержимого аккумулятора и регистра (A) - (ri)

DAD ri

00ri001

1

Сложение пары регистров с содержимым регистра HL: HL <- (HL) + ( ri-1ri)

11К2110

ADI

000

2

К содержимому аккумулятора прибавить содержимое 2-ого байта команды

A <- (A) + <B2>

10К2ri

ADD ri

000

1

Содержимое аккумулятора сложить с содержимым регистра. Результат записать в аккумулятор A <- (A) + (ri)

ADC ri

001

1

То же, но к сумме прибавить содержимое триггера переноса A <- (A) + (ri) + (Tc)

ACI

001

2

A <- (A) + <B2> + (Tc)

SUI

010

2

A <- (A) - <B2>

SBI

011

2

A <- (A) - <B2> - (Tc)

ANI

100

2

A <- (A) Λ <B2>

XRI

101

2

A <- (A) mod2 <B2>

ORI

110

2

A <- (A) v <B2>

CPI

111

2

Сравнение (A) - <B2>

Операции циклического сдвига

00К3111

RLC

000

1

Циклический сдвиг влево без переноса

Am+1 <- (Am); A0 <- (A7); Tc <- (A7)

RRC

001

1

Циклический сдвиг вправо без переноса

Am <- (Am+1); A7 <- (A0); Tc <- (A0)

RAL

010

1

Циклический сдвиг влево с учетом Тс

Am+1 <- (Am); A0 <- (Тс); Tc <- (A7)

RAR

011

1

Циклический сдвиг вправо с учетом Тс

Am <- (Am+1); A7 <- (Tc); Tc <- (A0)

Операции перехода

Продолжение таблицы 1

Мнемоника

Структура команды

Количество байт

Операция

JMP

11000011

3

Безусловный переход. Счетчику присваивается адрес, который содержит третий и второй байт команды

PC <- <B3B2>

Условный переход

11K4010

JNZ

000

3

Если значение триггера признака нуля будет равно нулю, то счетчику присвоить содержимое 2-ого и 3-его байтов команды. В противном случае продолжать текущую последовательность команд в алгоритме (Tz) = 0, то РС <- <B3B2>

JZ

001

3

(Tz) = 1, то РС <- <B3B2>

JNC

010

3

(Tc) = 0, то РС <- <B3B2>

JC

011

3

(Tc) = 1, то РС <- <B3B2>

JPO

100

3

(Tp) = 0, то РС <- <B3B2>

JPE

101

3

(Tp) = 1, то РС <- <B3B2>

JP

110

3

(Ts) = 0, то РС <- <B3B2>

JM

111

3

(Ts) = 1, то РС <- <B3B2>

Операции ввода и вывода

IN

11011011

2

Запись содержимого 2-ого байта команды на внешней шине данных в аккумулятор

A <- (ШД)

OUT

11010011

2

ШД <- (A)

Прочие операции

EI

11111011

1

Разрешение прерывания

DI

11110011

1

Блокировка прерывания

HLT

01110110

1

Останова

Теперь одно число готово к выполнению сложения. Необходимо второе число, которое находиться в соседней ячейке памяти 0277. Для доступа к этой ячейке памяти данный адрес должен быть в паре регистров HL. Сейчас там находиться адрес 0276. Можно перезаписать адрес в пару регистров, используя трехбайтовую команду непосредственной загрузки регистров. Но для более быстрого выполнения программы можно воспользоваться однобайтовой командой инкрементирования, т. е. увеличения содержимого пары регистров на единицу. Данная команда будет иметь следующее описание: .

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

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

То, что описано словами можно показать в виде алгоритма, представленного на рисунке 1.

Теперь необходимо составить программу, по которой процессор будет выполнять сложение двух чисел. Для этого, необходимо в соответствии с описаниями операций выбрать из системы команд МПК КР580 (таблица 1) соответствующие команды.

Для выполнения загрузки пары регистров необходима команда LXI. В таблице 1, колонка «Мнемоника» показывает, как буквенно описывается та или иная команда. В данном случае команда LXI описывается следующим образом: LXI H. Как видно, после команды LXI через пробел вместо ri пишется имя регистра в который идет загрузка данных. Необходимо учитывать, что в команде пишется только один регистр, первый (H) в паре, несмотря на то, что загружается пара регистров. Загрузка пары регистров подразумевается самой командой. Поэтому для простоты описания пишется имя первого регистра пары.

Рисунок 1 – Алгоритм сложения двух чисел

В колонке «Структура команды» описывается, как команда выглядит в двоичном коде. Для LXI первые два бита и последние три постоянны. Они составляют код операции. Вместо значения ri подставляется код регистра Н (100). Таким образом, команда LXI H в двоичном коде будет иметь вид: 00 100 001.

По третьей колонке таблицы 1 можно узнать количество байт, которое занимает та или иная команда. Команда LXI занимает три байта. Первый байт занимает код операции, который был описан выше. Второй и третий байт – это данные, которые должны быть загружены в пару регистров. Для нашей задачи, в последних байтах записан адрес ячейки памяти 0276. Причем, ранее говорилось, что в трехбайтовых командах третий байт является старшим. Таким образом, во втором байте команды будет храниться значение 76, а в третьем байте 02.

По колонке «Операция» можно посмотреть, что выполняет команда и ее описание. В частности для команды LXI написано, что это непосредственная загрузка пары регистров, а кроме того краткое описание команды. Запись ri <- <B3> показывает, что в первый регистр пары (регистр Н) необходимо записать содержимое третьего байта (запись <B3>). Соответственно запись ri+1 <- <B2> обозначает, что во второй регистр пары (регистр L) необходимо записать содержимое второго байта команды.

Аналогично по таблице 1 анализируются все команды. Далее по ходу некоторые команды будут еще разобраны. В таблице 2 представлена программа

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

Таблица 2

Адрес хранения команды

Мнемоника

Структура

Описание

2 - ая

16 - ая

0050

LXI H

00100001

21

0051

-

01110110

76

B2=76

0052

-

00000010

02

B3=02

0053

MOV A, M

01111110

7E

0054

INX H

00100011

23

0055

ADD M

10000110

86

0056

MOV M, A

01110111

77

Рассмотрим подробно эту программу. В первой колонке таблицы 2 пишется адрес ячейки памяти, в которой хранится команда. Когда программа загружается в память, то все ее команды записываются в ячейки памяти по порядку друг за другом с возрастающими адресами. Счетчик в микропроцессоре устанавливается в состояние, которое соответствует адресу первой команды. После выборки первой команды, счетчик увеличивает свое состояние на единицу и выбирается следующая команда и т. д. Но при включении системы процессор автоматически резервирует часть адресов под нужды системы. Это адреса 0000 – 0049. Поэтому при записи программ эти адреса не используются. Таким образом, все программы должны начинаться, как минимум с адреса 0050. Это и отражено в таблице 2. Первый байт первой команды хранится в ячейки памяти 0050. Все последующие байты и команды хранятся в следующих ячейках памяти по возрастанию адреса. Все остальные колонки таблицы программы схожи с таблицей 1 за исключением того, что в ней еще указывается шестнадцатеричный код команды (поле «Структура»).

Теперь рассмотрим, как сформировались команды.

Команда LXI была подробно рассмотрена выше. Эта команда трехбайтовая, а каждая ячейка памяти в МПК КР580 может хранить только 8 – разрядные числа. Поэтому каждый байт команды храниться в последующей ячейке памяти. Таким образом, команда LXI занимает три ячейки памяти 0050, 0051, 0052.

Следующая команда MOV обеспечивает пересылку содержимого одного регистра в другой. В нашем случае из регистра М в регистр А. Таким образом, команда будет иметь вид: MOV A, M. Таким образом, в команде сначала указывается имя регистра в который пересылается, а потом из которого. Точно

так же составляется и код команды. Первые два бита (01) – это код команды, следующие три бита это код регистра в который принимаются данные (регистр А – 111), а последние три бита код регистра из которого принимаются данные (регистр М – 110).

Следующая команда INX H увеличивает содержимое пары регистров на единицу. Это команда из группы команд приращения. По своей структуре она во многом схожа с командой LXI, тока является однобайтовой и занимает только одну ячейку памяти.

Команда ADD относится к группе команд «Арифметические операции». Вся эта группа команд имеет общий формат 10K2ri (таблица 1). Все команды этой группы начинаются с кода 10. Дальше вместо К2 подставляется код из колонки «Структура команды», который соответствует конкретной команде. Вместо ri подставляется код регистра, в котором находиться нужный операнд для выполнения арифметической операции. В команде указывается только один регистр, т. к. другой операнд по умолчанию должен находиться в регистре А. Так для команды сложения ADD M структура в двоичной системе будет иметь вид: 10 000 110, где 000 – это код команды ADD (сложение аккумулятора с регистром), а 110 – это код регистра М. Данный формат действует до тех пор, пока в таблице не встретится пустая строка, либо не начнется другая группа команд. Так формат команды 10K2ri будет действовать, начиная от команды ADD и заканчивая командой CMR. После этой команды идет пустая строка, значит, команда DAD под этот формат не попадает.

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

Для рассмотрения следующего примера необходимо разобраться с видами сдвига двоичных чисел. Существует четыре вида сдвига.

1. Сдвиг влево без использование триггера Тс. Принцип сдвига показан на рисунке 2.

Рисунок 2 – Принцип сдвига двоичного числа влево без триггера Тс

Из рисунка видно, что при сдвиге двоичного числа влево каждый младший разряд перемещается в соседний старший, при этом самый старший разряд числа D7 перемещается в триггер Тс, который находится в регистре признаков, и одновременно передается в младший разряд числа.

2. Сдвиг влево с использованием триггера Тс. Принцип сдвига показан на рисунке 3.

Рисунок 3 – Принцип сдвига двоичного числа влево с триггером Тс

В отличии от предыдущего способа сдвига, в младший разряд числа передается разряд, который был записан в триггере Тс.

3. Сдвиг вправо без использования триггера Tс. Принцип показан на рисунке 4. При этом способе каждый старший разряд перемещается в соседний младший. Самый младший разряд D0 передается в триггер Тс и одновременно в старший разряд D7.

Рисунок 4 – Принцип сдвига двоичного числа вправо без триггера Тс

4. Сдвиг вправо с использованием триггера Тс. Принцип сдвига показан на рисунке 5.

Рисунок 5 – Принцип сдвига двоичного числа вправо с триггером Тс

В данном случае содержимое триггера Тс передается в старший разряд двоичного числа.

Теперь рассмотри пример составления программ со сдвигом двоичного числа.

Задача. Произвести арифметический сдвиг вправо числа, хранящегося в регистре D.

Решение. Арифметический сдвиг подразумевает, что знаковый разряд двоичного числа при сдвиге останется неизменным. Сдвиг числа всегда осуществляется в аккумуляторе. Поэтому первым действием необходимо переместить двоичное число из регистра D в регистр А.

Дальше необходимо сохранить знаковый (старший) разряд. Сохранить его можно в триггере Тс. Для этого необходимо сдвинуть число влево без триггера Тс. Допустим исходное число было 10110110. Тогда, после сдвига в аккумуляторе будет число: 01101101, а в триггере Тс = 1.

Теперь необходимо вернуть число в аккумуляторе в исходное состояние, т. к. сдвигать число необходимо вправо, а не влево. Поэтому следующий командой необходимо сдвинуть число вправо с использованием триггера Тс. После сдвига в числа влево в аккумуляторе находится число 01101101, а в триггере Тс = 1. После сдвига, в аккумуляторе восстановится исходное число, т. к. разряд из триггера Тс будет перемещен в старший разряд аккумулятора, а младший разряд аккумулятора перепишется в триггер Тс. В результате в аккумуляторе будет число 10110110, а в триггере Тс останется единица.

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

На рисунке 6 представлена блок – схема программы.

Запись Сдв. в Л без Тс обозначает, что происходит сдвиг влево числа, находящегося в аккумуляторе без использования триггера Тс. Соответственно читаются и другие записи алгоритма. В таблице 3 показана программа выполнения арифметического сдвига.

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

Таблица 3

Адрес хранения команды

Мнемоника

Структура

Описание

2 - ая

16 - ая

0050

MOV A, D

01111010

7A

0051

RLC

00000111

07

Сдв. в Л (А) без Тс

0052

RAR

00011111

1F

Сдв. в Л (А) c Тс

0053

RAR

00011111

1F

Сдв. в Л (А) c Тс

Рисунок 6 – Алгоритм выполнения арифметического сдвига