Тестовые программы
Программа 1
Адрес |
Код команды |
Мнемоника |
Комментарии |
000 |
041 |
LXI H |
Загрузка начального адреса памяти в регистровую пару HL |
001 |
200 |
B2 |
|
002 |
000 |
B3 |
|
003 |
001 |
LXI B |
Запись исходных данных в регистры B и C |
004 |
001 |
B2 |
|
005 |
010 |
B3 |
|
006 |
160 |
MOV M, B |
Запоминание B |
007 |
043 |
INX H |
Формирование следующего адреса |
010 |
161 |
MOV M, C |
Запоминание C |
011 |
166 |
HLT |
Останов |
Программа 1 позволяет загрузить данные в ячейку памяти по адресу, хранящемуся в регистровой паре HL.
Содержимое памяти:
Адрес |
Содержимое до выполнения |
Содержимое после выполнения |
|||
H |
L |
||||
000 |
200 |
000 |
010 |
||
000 |
201 |
000 |
001 |
Программа 2
Адрес |
Код команды |
Мнемоника |
Комментарии |
000 |
061 |
LXI SP |
Загрузка указателя стека |
001 |
200 |
B2 |
|
002 |
000 |
B3 |
|
003 |
301 |
POP B |
Считывание из стека |
004 |
041 |
INR C |
Инкрементация C |
005 |
005 |
DCR B |
Декрементация B |
006 |
305 |
PUSH B |
Загрузка в стек |
007 |
166 |
HLT |
Останов |
Программа 2 иллюстрирует работу стека. Она считывает данные из стека (POP), модифицирует их (INR и DEC) и загружает их назад (PUSH).
Содержимое памяти:
Адрес |
Содержимое до выполнения |
Содержимое после выполнения |
|||
H |
L |
||||
000 |
200 |
222 |
223 |
||
000 |
201 |
333 |
332 |
Поскольку в процессоре К580 стек моделируется в памяти, то для указания месторасположения стека в памяти необходимо инициализировать указатель стека, который является адресом перового элемента стека.
Элементами стека являются двухбайтные слова, а значит, при записи и считывании из стека необходимо изменять указатель на два.
При загрузке в стек он «растет» в направлении меньших адресов памяти (указатель стека уменьшается).
При выполнении команды PUSH RP загружаются ячейки памяти с адресами (SP – 1) и (SP – 2), а при выполнении POP RP извлекаются ячейки с адресами (SP) и (SP + 1). Это сделано для, того чтобы эти команды были взаимообратными. Т. е. если сначала выполнить команду POP RP (или PUSH RP), то сразу после нее можно выполнять команду PUSH RP (POP RP) без каких-либо дополнительных преобразований.
Программа 3
Адрес |
Код команды |
Мнемоника |
Комментарии |
000 |
041 |
LXI H |
Загрузка начального адреса памяти в регистровую пару HL |
001 |
200 |
B2 |
|
002 |
000 |
B3 |
|
003 |
076 |
MVI A |
Запись в аккумулятор числа 010 |
004 |
010 |
B2 |
|
005 |
206 |
ADD M |
Суммирования значения аккумулятора и ячейки памяти, запись в аккумулятор |
006 |
167 |
MOV M, A |
Запоминание А |
007 |
166 |
HLT |
Останов |
Программа 3 суммирует содержимое аккумулятора и ячейки памяти и записывает результат в память. В результате значение из памяти увеличивается на 010. Поскольку запись результата происходит в ту ячейку памяти, в которой хранилось второе слагаемое, то при повторном запуске программы, содержимое ячейки памяти увеличится еще на 010:
Итерация |
Содержимое L = 200 |
до выполнения программы |
010 |
1 |
020 |
2 |
030 |
3 |
040 |
4 |
050 |
5 |
060 |
6 |
070 |
Программа 3.1
Адрес |
Код команды |
Мнемоника |
Комментарии |
000 |
041 |
LXI H |
Загрузка начального адреса памяти в регистровую пару HL |
001 |
200 |
B2 |
|
002 |
000 |
B3 |
|
003 |
076 |
MVI A |
Запись в аккумулятор числа 100 |
004 |
100 |
B2 |
|
005 |
006 |
MVI B |
Запись в B числа 010 |
006 |
010 |
B2 |
|
007 |
220 |
SUB B |
Вычитание (A)-(B) |
010 |
167 |
MOV M, A |
Запоминание А |
011 |
166 |
HLT |
Останов |
Программа 3.1 реализует вычитание двух чисел, одно из которых находится в регистре B и записывает результат в память.
(A) = 100 (B) = 010 => (A) – (B) = 070
Адрес |
Содержимое до выполнения |
Содержимое после выполнения |
|||
H |
L |
||||
000 |
200 |
000 |
070 |
Программа 3.2
Адрес |
Код команды |
Мнемоника |
Комментарии |
000 |
041 |
LXI H |
Загрузка начального адреса памяти в регистровую пару HL |
001 |
200 |
B2 |
|
002 |
000 |
B3 |
|
003 |
076 |
MVI A |
Запись в аккумулятор числа 043 ( = 23 в двоично-десятичном коде) |
004 |
043 |
B2 |
|
005 |
006 |
MVI B |
Запись в B числа 130 ( = 58 в двоично-десятичном коде) |
006 |
130 |
B2 |
|
007 |
200 |
ADD B |
Суммирование (A) + (B) |
010 |
047 |
DAA |
Двоично-десятичная коррекция |
011 |
167 |
MOV M, A |
Запоминание А |
012 |
166 |
HLT |
Останов |
Программа 3.2 суммирует двоично-десятичные числа, содержащиеся в аккумуляторе и регистре B. Результат сохраняется в памяти.
Двоично-десятичное суммирование происходит как обычное суммирование в двоичных кодах, но добавляется команда DAA, которая производит двоично-десятичную коррекцию результата.
(A) = 232/10 = 0438
(B) = 582/10 = 1308
(A) + (B) = 812/10 = 2008
Адрес |
Содержимое до выполнения |
Содержимое после выполнения |
|||
H |
L |
||||
000 |
200 |
000 |
200 |
Программа 3.3
Адрес |
Код команды |
Мнемоника |
Комментарии |
000 |
041 |
LXI H |
Загрузка начального адреса памяти в регистровую пару HL |
001 |
200 |
B2 |
|
002 |
000 |
B3 |
|
003 |
006 |
MVI B |
Запись вычитаемого (N) в B (050 = 28 в двоично-десятичном коде) |
004 |
050 |
B2 |
|
005 |
076 |
MVI A |
Запись в аккумулятор числа 231 ( = 99 в двоично-десятичном коде) |
006 |
231 |
B2 |
|
007 |
220 |
SUB B |
Вычитание (99 - N) |
010 |
170 |
MOV A, B |
Пересылка B = (99 - N) |
011 |
004 |
INR B |
Инкрементация B = (99 - N) +1 |
012 |
076 |
MVI A |
Запись в аккумулятор числа 123 ( = 53 в двоично-десятичном коде) |
013 |
123 |
B2 |
|
014 |
200 |
ADD B |
Суммирование (A) + (B) |
015 |
047 |
DAA |
Двоично-десятичная коррекция |
016 |
167 |
MOV M, A |
Запоминание А |
017 |
166 |
HLT |
Останов |
Программа 3.3 производит вычитание двоично-десятичных чисел, хранящихся в аккумуляторе и регистре B. Поскольку команда DAA не корректирует результат вычитания, нельзя напрямую вычесть числа, а затем скорректировать результат, как это было при сложении. Решением этой проблемы является замена вычитания на сложение в дополнительных кодах. В программе сначала происходит преобразование вычитаемого N (оно хранится в B) из прямого кода в дополнительный по формуле (99 – N) + 1. Затем происходит сложение двоично-десятичных чисел, как в программе 3.2.
(A) = 532/10 = 1238
(B) = 282/10 = 0508
(A) – (B) = 252/10 = 0458
Адрес |
Содержимое до выполнения |
Содержимое после выполнения |
|||
H |
L |
||||
000 |
200 |
000 |
045 |
Программа 3.4
Адрес |
Код команды |
Мнемоника |
Комментарии |
000 |
001 |
LXI B |
Загрузка в регистровую пару (B)(С) 16-разрядного числа 047 132 |
001 |
132 |
B2 |
|
002 |
047 |
B3 |
|
003 |
021 |
LXI D |
Загрузка в регистровую пару (D)(E) 16-разрядного числа 121 324 |
004 |
324 |
B2 |
|
005 |
121 |
B3 |
|
006 |
173 |
MOV A, E |
Пересылка из (E) в (A) |
007 |
201 |
ADD C |
Суммирование (А) + (С) |
010 |
062 |
STA |
Запоминание младшего байта результата по адресу 200 |
011 |
200 |
B2 |
|
012 |
000 |
B3 |
|
013 |
172 |
MOV A, D |
Пересылка из (D) в (A) |
014 |
210 |
ADC B |
Сложение с переносом (A) + (B) + c |
015 |
062 |
STA |
Запоминание старшего байта результата по адресу 201 |
016 |
201 |
B2 |
|
017 |
000 |
B3 |
|
020 |
166 |
HLT |
Останов |
Программа 3.4 предназначена для сложения двух 16-ти разрядных чисел и записи результата в память, при помощи прямой адресации. В программе сначала складываются младшие байты командой ADD, а затем складываются старшие байты с учетом переноса (ADC).
(B)(C) = 047 1328
(D)(E) = 121 3248
(B)(C) + (D)(E) = 171 1568
Адрес |
Содержимое до выполнения |
Содержимое после выполнения |
|||
H |
L |
||||
000 |
200 |
000 |
156 |
||
000 |
201 |
000 |
171 |
Программа 3.5
Адрес |
Код команды |
Мнемоника |
Комментарии |
000 |
001 |
LXI B |
Загрузка в регистровую пару (B)(С) начального адреса памяти |
001 |
200 |
B2 |
|
002 |
000 |
B3 |
|
003 |
021 |
LXI D |
Загрузка в регистровую пару (D)(E) 16-разрядного числа 121 324 |
004 |
324 |
B2 |
|
005 |
121 |
B3 |
|
006 |
041 |
LXI H |
Загрузка в регистровую пару (H)(L) 16-разрядного числа 047 132 |
007 |
132 |
B2 |
|
010 |
047 |
B3 |
|
011 |
173 |
MOV A, E |
Пересылка из (E) в (A) |
012 |
225 |
SUB L |
Вычитание (A) - (L) |
013 |
002 |
STAX B |
Запоминание младшего байта |
014 |
003 |
INX B |
Формирование следующего адреса |
015 |
172 |
MOV A, D |
Пересылка из (D) в (A) |
016 |
234 |
SBB H |
Вычитание с заемом (A) - (H) - c |
017 |
002 |
STAX B |
Запоминание старшего байта |
020 |
166 |
HLT |
Останов |
Программа 3.5 реализует вычитание двух 16-ти разрядных чисел с последующей записью результата в память, используя команды косвенной адресации. В программе сначала вычитаются младшие байты командой SUB, а затем вычитаются старшие байты с учетом заёма (SBB).
(D)(E) = 121 3248
(H)(L) = 047 1328
(D)(E) – (H)(L) = 041 1628
Адрес |
Содержимое до выполнения |
Содержимое после выполнения |
|||
H |
L |
||||
000 |
200 |
000 |
162 |
||
000 |
201 |
000 |
041 |
Программа 4
Адрес |
Код команды |
Мнемоника |
Комментарии |
000 |
227 |
SUB A |
Обнуление A |
001 |
041 |
LXI H |
Загрузка начального адреса памяти |
002 |
011 |
B2 |
|
003 |
000 |
B3 |
|
004 |
167 |
MOV M, A |
Запоминание А (обнуление ячейки памяти) |
005 |
043 |
INX H |
Формирование следующего адреса |
006 |
303 |
JMP |
Безусловный переход по адресу 004 |
007 |
004 |
B2 |
|
010 |
000 |
B3 |
Программа 4 предназначена для обнуления определенной области памяти. Она реализована в виде цикла, но является некорректной из-за отсутствия условия выхода из цикла. В результате ее исполнения обнуляется не только необходимая область, но и почти вся остальная память. В том числе обнуляются ячейки 000-003, т. е. удаляются первые четыре команды программы.
Чтобы исправить программу нужно в нее добавить условие выхода из цикла. Например, можно сравнивать младший байт адреса с числом 040 и когда они сравняются прекратить выполнение программы:
Адрес |
Код команды |
Мнемоника |
Комментарии |
000 |
227 |
SUB A |
Обнуление A |
001 |
041 |
LXI H |
Загрузка начального адреса памяти |
002 |
011 |
B2 |
|
003 |
000 |
B3 |
|
004 |
167 |
MOV M, A |
Запоминание А (обнуление ячейки памяти) |
005 |
076 |
MVI A |
Загрузка в А числа 040 |
006 |
040 |
B2 |
|
007 |
275 |
CMP L |
Сравнение 040 с (L) |
010 |
312 |
JZ |
Условный переход. При равенстве (L) и (A) останавляваем программу |
011 |
020 |
B2 |
|
012 |
000 |
B3 |
|
013 |
227 |
SUB A |
Повторное обнуление А |
014 |
043 |
INX H |
Формирование следующего адреса |
015 |
303 |
JMP |
Безусловный переход по адресу 004 |
016 |
004 |
B2 |
|
017 |
000 |
B3 |
|
020 |
166 |
HLT |
Останов |
Программа 5
Адрес |
Код команды |
Мнемоника |
Комментарии |
000 |
006 |
MVI B |
Загрузка в B числа 200 |
001 |
200 |
B2 |
|
002 |
076 |
MVI A |
Загрузка в А числа 001 |
003 |
001 |
B2 |
|
004 |
250 |
XRA B |
Сложение по модулю 2: (А) xor (В) |
005 |
027 |
RAL |
Цикл. сдвиг влево через перенос |
006 |
061 |
LXI SP |
Загрузка указателя стека |
007 |
202 |
B2 |
|
010 |
000 |
B3 |
|
011 |
365 |
PUSH PSW |
Загрузка в стек PSW |
012 |
166 |
HLT |
Останов |
Программа 5 иллюстрирует формирование слова состояния процессора:
Мнемоника команды |
Значение PSW |
|
(A) |
Flags |
|
MVI B b2 |
xxxxxxxx |
xx0x0x1x |
MVI A b2 |
00000001 |
xx0x0x1x |
XRA B |
10000001 |
10000110 |
RAL |
00000011 |
10000111 |
LXI SP b2 b3 |
00000011 |
10000111 |
PUSH PSW |
00000011 |
10000111 |
HLT |
00000011 |
10000111 |
Содержимое памяти:
Адрес |
Содержимое до выполнения |
Содержимое после выполнения |
|||
H |
L |
||||
000 |
200 |
000 |
207 |
||
000 |
201 |
000 |
002 |
Программа 6
Адрес |
Код команды |
Мнемоника |
Комментарии |
H = 100 |
166 |
HLT |
Останов |
L = 200 |
Программа 6 демонстрирует работу в «клавиатурном» режиме. После перехода в этот режим работу стенда вводится команда JMP 200 100. В результате ее выполнения в счетчик команд загружается адрес H = 100, L = 200, по которому находится 6-я программа. После выхода из «клавиатурного» режима начинается выполнение программы и происходит останов.
Программа 7
Адрес |
Код команды |
Мнемоника |
Комментарии |
000 |
061 |
LXI SP |
Загрузка указателя стека |
001 |
200 |
B2 |
|
002 |
000 |
B3 |
|
003 |
361 |
POP PSW |
Извлечение из стека PSW |
004 |
*** |
*** |
Код одной из восьми команд условных переходов: JNZ, JZ, JNC, JC, JPO, JPE, JP или JM |
005 |
000 |
B2 |
|
006 |
000 |
B3 |
|
007 |
166 |
HLT |
Останов |
|
|||
200 |
*** |
--- |
Слово состояния процессора, хранящееся в стеке |
201 |
000 |
--- |
Программа 7 иллюстрирует работу команд условного перехода.
В ячейки памяти L = 004 и L = 200, заносится одна из комбинаций кодов представленных в таблице:
Содержимое ячейки L = 004 |
Содержимое ячейки L = 200 |
||||||
код |
мнемоника |
код |
мнемоника |
код |
Flags |
код |
Flags |
302 |
JNZ |
312 |
JZ |
002 |
00000010 |
102 |
01000010 |
322 |
JNC |
332 |
JC |
002 |
00000010 |
003 |
00000011 |
342 |
JPO |
352 |
JPE |
002 |
00000010 |
006 |
00000110 |
362 |
JPO |
372 |
JM |
002 |
00000010 |
202 |
10000010 |
Каждая из комбинаций представляет собой код операции команды условного перехода и значение, которое записывается в регистр флагов.
Пример: 302 – JNZ
002 – Flags = 00000010
При этой комбинации все флаги сбрасываются в нули, и устанавливается переход по нулевому значению флага Z. Поскольку Z=0 условный переход осуществляться будет и программа зацикливается между первыми тремя командами. Если в ячейку L=200 записать 102, то флаг Z установится в 1. В результате этого условный переход осуществляться не будет, и будет выполнена команд HLT.
Все происходит аналогично для других комбинаций.
Программа 8
Адрес |
Код команды |
Мнемоника |
Комментарии |
000 |
061 |
LXI SP |
Загрузка указателя стека |
001 |
200 |
B2 |
|
002 |
000 |
B3 |
|
003 |
315 |
CALL |
Вызов подпрограммы по адресу L = 100 |
004 |
100 |
B2 |
|
005 |
000 |
B3 |
|
006 |
166 |
HLT |
Останов |
|
|||
100 |
311 |
RET |
Возврат из подпрограммы |
Программа 8 демонстрирует работу команд CALL и RET. Команда CALL предназначена для вызова подпрограммы, находящейся по указанному адресу (L = 100). При этом в стек загружается значение счетчика команд, которое затем можно извлечь из стека командой RET – возврат из подпрограммы. В этом и заключается отличие команды CALL от команды JMP. Поскольку JMP не запоминает состояние счетчика команд, то затем нельзя вернуться из подпрограммы.
Программа 9
Адрес |
Код команды |
Мнемоника |
Комментарии |
000 |
061 |
LXI SP |
Загрузка указателя стека |
001 |
200 |
B2 |
|
002 |
000 |
B3 |
|
003 |
317 |
RST 1 |
Вызов подпрограммы по адресу L = 010 |
004 |
166 |
HLT |
Останов |
|
|||
010 |
311 |
RET |
Возврат из подпрограммы |
Программа 9 поясняет принцип работы команды RST N. Эта команда предназначена для вызова подпрограммы по адресу H=000 L=0N0. Принцип работы команды RST очень похож на принцип работы команды CALL, но существуют некоторые различия. Во-первых, RST – это однобайтная программа, а значит на ее выполнение нужно меньше обращений к памяти (3 машинных цикла), чем для выполнения CALL (5 машинных циклов). Во-вторых, RST может адресовать только 64 байта памяти (адреса 000, 010, 020, 030, 040, 050, 060 и 070).
Адрес |
Шина данных |
000 |
061 |
001 |
067 |
002 |
000 |
003 |
317 |
066 |
000 |
065 |
004 |
010 |
311 |
065 |
004 |
066 |
000 |
004 |
166 |
Программа 10
Адрес |
Код команды |
Мнемоника |
Комментарии |
000 |
061 |
LXI SP |
Загрузка указателя стека |
001 |
067 |
B2 |
|
002 |
000 |
B3 |
|
003 |
317 |
RST 1 |
Вызов подпрограммы |
004 |
166 |
HLT |
Останов |
010 |
327 |
RST 2 |
Вызов подпрограммы |
011 |
311 |
RET |
Возврат из подпрограммы |
020 |
337 |
RST 3 |
Вызов подпрограммы |
021 |
311 |
RET |
Возврат из подпрограммы |
030 |
347 |
RST 4 |
Вызов подпрограммы |
031 |
311 |
RET |
Возврат из подпрограммы |
040 |
357 |
RST 5 |
Вызов подпрограммы |
041 |
311 |
RET |
Возврат из подпрограммы |
050 |
311 |
RET |
Возврат из подпрограммы |
Программа 10 иллюстрирует работу нескольких прерывающих друг друга вложенных программ. Вызов подпрограмм во всех случаях осуществляется командой RST.