Архитектура процессора 8080
|
Коды регистров и пар регистров, используемые в командах МП
Регистры |
||
Код |
Имя ( r ) |
|
000 |
В |
|
001 |
С |
|
010 |
D |
|
011 |
E |
|
100 |
H |
|
101 |
L |
|
110 |
M (память) |
|
111 |
А (аккумулятор) |
Пары регистров |
|||
Код |
Имя пары |
Регистры пары |
|
старший |
младший |
||
00 |
B |
B |
C |
01 |
D |
D |
E |
10 |
H |
H |
L |
11 |
PSW |
A |
PSW |
Назначение разрядов регистра
признаков - PWS (processor status word)
Бит |
Флаг |
Действие |
7 |
S |
Знак (sign) S=1, если результат операции отрицательный |
6 |
Z |
Нуль (zero) Z=0, если результат нулевой |
5 |
0 |
|
4 |
AC |
Перенос из 3-го разряда (auxiliary carry) |
3 |
0 |
|
2 |
P |
Четность (parity) P=1, если результат содержит четное число "единиц" |
1 |
1 |
|
0 |
C |
Перенос (carry) при получении результата |
Форматы команд и способы адресации
В микропроцессоре i8080 (КР580ВМ80А) используются 11 форматов команд, коды операций (КОП) которых имеют различную длину (2, 5, 6 или 8 бит) и часто состоят из двух частей.
В зависимости от способа адресации команды могут быть одно-, двух- или трехбайтовыми.
В командах используются
четыре способа адресации:
регистровая (MOV rl, r2; ADD r; PCHL; ...);
косвенно-регистровая (MOV M, r; ADD M; PUSH; POP; ...);
непосредственная (MVI r, data 8; ADI data 8; ...);
прямая (LDA addr; SHLD addr; IN port; ...).
Так как под адрес выделяется 2 байта, адресное пространство составляет 64К.
Команды этого процессора бывают одно-, двух- и трехбайтными. В первом байте всегда содержится код операции.
Справочник по системе команд микропроцессора Intel 8080
Обозначения:
A, B, ..., L - названия 8-разрядных регистров.
BC, DE, HL - названия регистровых пар, образующих 16-разрядные регистры.
SP - 16-разрядный указатель стека.
PSW - слово состояния программы, содержит регистр флагов.
a16 - двухбайтовый адрес.
d8 - байт непосредственных данных.
d16 - два байта непосредственных данных.
pp - номер порта ввода-вывода.
Команда |
Код |
Описание |
ADD A |
87 |
A ¬ (A) + (A) |
ADD B |
80 |
A ¬ (B) + (A) |
ADD C |
81 |
A ¬ (C) + (A) |
ADD D |
82 |
A ¬ (D) + (A) |
ADD E |
83 |
A ¬ (E) + (A) |
ADD H |
84 |
A ¬ (H) + (A) |
ADD L |
85 |
A ¬ (L) + (A) |
ADD M |
86 |
A ¬ loc(HL) + (A) |
ADI d8 |
C6 |
A ¬ d8 + (A) |
ADC A |
8F |
A ¬ (A) + (A) + CY |
ADC B |
88 |
A ¬ (B) + (A) + CY |
ADC C |
89 |
A ¬ (C) + (A) + CY |
ADC D |
8A |
A ¬ (D) + (A) + CY |
ADC E |
8B |
A ¬ (E) + (A) + CY |
ADC H |
8C |
A ¬ (H) + (A) + CY |
ADC L |
8D |
A ¬ (L) + (A) + CY |
ADC M |
8E |
A ¬ loc(HL) + (A) + CY |
ACI d8 |
CE |
A ¬ d8 + (A) + CF |
ANA A |
A7 |
Проверка A |
ANA B |
A0 |
Логическое И B с A |
ANA C |
A1 |
Логическое И C с A |
ANA D |
A2 |
Логическое И D с A |
ANA E |
A3 |
Логическое И E с A |
ANA H |
A4 |
Логическое И H с A |
ANA L |
A5 |
Логическое И L с A |
ANA M |
A6 |
Логическое И loc(HL) с A |
ANI d8 |
E6 |
Логическое И непосредственные данные с A |
CALL a16 |
CD |
Передать управление подпрограмме по адресу aa |
CZ a16 |
CC |
Вызвать подпрограмму по адресу aa, если нуль |
СNZ a16 |
C4 |
То же, если не нуль |
СP a16 |
F4 |
То же, если плюс |
СM a16 |
FC |
То же, если минус |
CC a16 |
DD |
То же, если перенос |
CNC a16 |
D4 |
То же, если нет переноса |
CPE a16 |
EC |
То же, если четно |
CPO a16 |
E4 |
То же, если нечетно |
CMA |
2F |
Инвертировать A |
CMC |
3F |
Инвертировать перенос |
CMP A |
BF |
Установить флаг FZ |
CMP B |
B8 |
Сравнить A с B |
CMP C |
B9 |
Сравнить A с C |
CMP D |
BA |
Сравнить A с D |
CMP E |
BB |
Сравнить A с E |
CMP H |
BC |
Сравнить A с H |
CMP L |
BD |
Сравнить A с L |
CMP M |
BE |
Сравнить A с loc(HL) |
CPI d8 |
FC |
Сравнить A с данными, заданными в команде |
DAA |
27 |
Десятичная коррекция аккумулятора |
DAD |
B |
Сложить BC с HL |
DAD |
D |
Сложить DE с HL |
DAD |
H |
Сложить HL с HL (удвоение HL) |
DAD |
SP |
Сложить SP с HL |
DCR A |
3D |
A ¬ (A) - 1 (декремент A) |
DCR B |
05 |
B ¬ (B) - 1 |
DCR C |
0D |
C ¬ (C) - 1 |
DCR D |
15 |
D ¬ (D) - 1 |
DCR E |
1D |
E ¬ (E) - 1 |
DCR H |
25 |
H ¬ (H) - 1 |
DCR L |
2D |
L ¬ (L) - 1 |
DCR M |
3D |
loc (HL) ¬ (loc(HL)) -1 |
DCX B |
0B |
BC ¬ (BC) - 1 |
DCX D |
1B |
DE ¬ (DE) -1 |
DCX H |
2B |
HL ¬ (HL) - 1 |
DCX SP |
0B |
SP ¬ (SP) -1 |
DI |
F3 |
Запретить прерывания |
EI |
FB |
Разрешить прерывания |
HLT |
76 |
Останов процессора |
IN pp |
DB |
Ввести данные из порта pp |
INR A |
3C |
A ¬ (A) + 1 (инкрементировать A) |
INR B |
04 |
Инкрементировать B |
INR C |
0C |
Инкрементировать C |
INR D |
3C |
Инкрементировать D |
INR E |
3C |
Инкрементировать E |
INR H |
3C |
Инкрементировать H |
INR L |
3C |
Инкрементировать L |
INR M |
34 |
Инкрементировать содержимое loc(HL) |
INX B |
03 |
Инкрементировать BС |
INX D |
13 |
Инкрементировать DE |
INX H |
23 |
Инкрементировать HL |
INX SP |
33 |
Инкрементировать SP |
JMP a16 |
C3 |
Перейти по адресу a16 |
JZ a16 |
CA |
То же, если нуль |
JNZ a16 |
C2 |
То же, если не нуль |
JP a16 |
F2 |
То же, если плюс |
JM a16 |
FA |
То же, если минус |
JC a16 |
DA |
То же, если перенос |
JNC a16 |
D2 |
То же, если нет переноса |
JPE a16 |
EA |
Перейти по адресу a16, если паритет четный |
JPO a16 |
E2 |
Перейти по адресу a16, если паритет нечетный |
LDA aaaaa |
3A |
Загрузить A из ячeйки с адресом a16 |
LDAX B |
0A |
Загрузить A из ячeйки с адресом loc(BC) |
LDAX D |
1A |
Загрузить A из ячeйки с адресом loc(DE) |
LHLD a16 |
2A |
Загрузить в HL содержимое ячейки с адресом a16 |
LXI B,d16 |
01 |
Загрузить в BC непосредственные данные d16 |
LXI H,d16 |
21 |
Загрузить в HL непосредственные данные d16 |
LXI SP,d16 |
31 |
Загрузить в SP непосредственные данные d16 |
MOV A,B |
78 |
Переслать из A в B (B(A) ) |
MOV A,C |
79 |
Переслать из A в C |
MOV A,D |
7A |
Переслать из A в D |
MOV A,E |
7B |
Переслать из A в E |
MOV A,H |
7C |
Переслать из A в H |
MOV A,L |
7D |
Переслать из A в L |
MOV A,M |
7E |
Переслать из A в loc(HL) |
MOV B,A |
47 |
Переслать из B в A |
MOV B,C |
41 |
Переслать из B в C |
MOV B,D |
42 |
Переслать из B в D |
MOV B,E |
43 |
Переслать из B в E |
MOV B,H |
44 |
Переслать из B в H |
MOV B,L |
45 |
Переслать из B в L |
MOV B,M |
46 |
Переслать из B в loc(HL) |
MOV C,A |
4F |
Переслать из C в A |
MOV C,B |
48 |
Переслать из C в B |
MOV C,D |
4A |
Переслать из C в D |
MOV C,E |
4B |
Переслать из C в E |
MOV C,H |
4C |
Переслать из C в H |
MOV C,L |
4D |
Переслать из C в L |
MOV C,M |
4E |
Переслать из C в loc(HL) |
MOV D,A |
57 |
Переслать из D в A |
MOV D,B |
50 |
Переслать из D в B |
MOV D,C |
51 |
Переслать из D в C |
MOV D,E |
53 |
Переслать из D в E |
MOV D,H |
54 |
Переслать из D в H |
MOV D,L |
55 |
Переслать из D в L |
MOV D,M |
56 |
Переслать из D в loc(HL) |
MOV E,A |
5F |
Переслать из E в A |
MOV E,B |
58 |
Переслать из E в B |
MOV E,C |
59 |
Переслать из E в C |
MOV E,D |
5A |
Переслать из E в D |
MOV E,H |
5C |
Переслать из E в H |
MOV E,L |
5D |
Переслать из E в L |
MOV E,M |
5E |
Переслать из E в loc(HL) |
MOV H,A |
67 |
Переслать из H в A |
MOV H,B |
60 |
Переслать из H в B |
MOV H,C |
61 |
Переслать из H в C |
MOV H,D |
62 |
Переслать из H в D |
MOV H,E |
63 |
Переслать из H в E |
MOV H,L |
65 |
Переслать из H в L |
MOV H,M |
66 |
Переслать из H в loc(HL) |
MOV L,A |
6F |
Переслать из L в A |
MOV L,B |
68 |
Переслать из L в B |
MOV L,C |
69 |
Переслать из L в C |
MOV L,D |
6A |
Переслать из L в D |
MOV L,E |
6B |
Переслать из L в E |
MOV L,H |
6C |
Переслать из L в H |
MOV L,M |
6E |
Переслать из L в loc(HL) |
MOV M,A |
77 |
Переслать из M в A |
MOV M,B |
70 |
Переслать из M в B |
MOV M,C |
71 |
Переслать из M в C |
MOV M,D |
72 |
Переслать из M в D |
MOV M,E |
73 |
Переслать из M в E |
MOV M,H |
74 |
Переслать из M в H |
MOV M,L |
75 |
Переслать из M в L |
MVI A,d8 |
3E |
Переслать d8 в A |
MVI B,d8 |
06 |
Переслать d8 в B |
MVI C,d8 |
0E |
Переслать d8 в C |
MVI D,d8 |
16 |
Переслать d8 в D |
MVI E,d8 |
1E |
Переслать d8 в E |
MVI H,d8 |
26 |
Переслать d8 в H |
MVI L,d8 |
2E |
Переслать d8 в L |
MVI M,d8 |
36 |
Переслать d8 в loc(HL) |
NOP |
00 |
Нет операции |
ORA A |
B7 |
Проверить A и сбросить перенос |
ORA B |
B0 |
Логичеcкая операция B ИЛИ A |
ORA C |
B1 |
Логичеcкая операция C ИЛИ A |
ORA D |
B2 |
Логичеcкая операция D ИЛИ A |
ORA E |
B3 |
Логичеcкая операция E ИЛИ A |
ORA H |
B4 |
Логичеcкая операция H ИЛИ A |
ORA L |
B5 |
Логичеcкая операция L ИЛИ A |
ORA M |
B6 |
Логичеcкая операция M ИЛИ A |
ORI d8 |
F6 |
Логичеcкая операция d8 ИЛИ A |
OUT pp |
D3 |
Записать A в порт pp |
PCHL |
E9 |
Передать управление по адресу в HL |
POP B |
C1 |
Извлечь слово из стека в BC |
POP D |
D1 |
Извлечь слово из стека в DE |
POP H |
E1 |
Извлечь слово из стека в HL |
POP PSW |
F1 |
Извлечь слово из стека в PSW |
PUSH B |
C5 |
Поместить в стек содержимое BC |
PUSH D |
D5 |
Поместить в стек содержимое DE |
PUSH H |
E5 |
Поместить в стек содержимое HL |
PUSH PSW |
F5 |
Поместить в стек содержимое PSW |
RAL |
17 |
Циклический сдвиг CY + A влево |
RAR |
1F |
Циклический сдвиг CY + A вправо |
RLG |
07 |
Сдвинуть A влево на один разряд с переносом |
RRG |
0F |
Сдвинуть A вправо на один разряд с переносом |
RET |
C9 |
Возврат из подпрограммы |
RZ |
C8 |
Возврат из подпрограммы, если FZ=0 |
RNZ |
C0 |
Возврат из подпрограммы, если FZ=1 |
RP |
F0 |
Возврат из подпрограммы, если FP=1 |
RM |
F8 |
Возврат из подпрограммы, если FP=0 |
RC |
D8 |
Возврат из подпрограммы, если FC=1 |
RNC |
D0 |
Возврат из подпрограммы, если FC=0 |
RPE |
E8 |
Возврат из подпрограммы, если паритет четный |
RPO |
E0 |
Возврат из подпрограммы, если паритет нечетный |
RST 0 |
C7 |
Запуск программы с адреса 0 |
RST 1 |
CF |
Запуск программы с адреса 8h |
RST 2 |
D7 |
Запуск программы с адреса 10h |
RST 3 |
DF |
Запуск программы с адреса 18h |
RST 4 |
E7 |
Запуск программы с адреса 20h |
RST 5 |
EF |
Запуск программы с адреса 28h |
RST 6 |
F7 |
Запуск программы с адреса 30h |
RST 7 |
FF |
Запуск программы с адреса 38h |
SPHL |
F9 |
Загрузить SP из HL |
SHLD a16 |
22 |
Записать HL по адресу a16 |
STA a16 |
32 |
Записать A по адресу a16 |
STAX B |
02 |
Записать A по адресу loc(BC) |
STAX D |
12 |
Записать A по адресу loc(DE) |
STC |
37 |
Установить флаг переноса (CF=1) |
SUB A |
9F |
Вычесть А из А (очистить А) |
SUB B |
98 |
Вычесть B из А |
SUB C |
99 |
Вычесть C из А |
SUB D |
9A |
Вычесть D из А |
SUB E |
9B |
Вычесть E из А |
SUB H |
9C |
Вычесть H из А |
SUB L |
9D |
Вычесть L из А |
SUB M |
9E |
Вычесть M из А |
SUI d8 |
DE |
Вычесть d8 из А |
SBB A |
9F |
Вычесть А из А (очистить А) |
SBB B |
98 |
Вычесть c заемом B из А |
SBB C |
99 |
Вычесть c заемом C из А |
SBB D |
9A |
Вычесть c заемом D из А |
SBB E |
9B |
Вычесть c заемом E из А |
SBB H |
9C |
Вычесть c заемом H из А |
SBB L |
9D |
Вычесть c заемом L из А |
SBB M |
9E |
Вычесть c заемом M из А |
SBI d8 |
DE |
Вычесть c заемом d8 из А |
XCHG |
EB |
Обмен содержимым DE и HL |
XTHL |
E3 |
Обмен содержимого вершины стека с содержимым HL |
XRA A |
AF |
Исключающее ИЛИ A с A (очистка A) |
XRA B |
A8 |
Исключающее ИЛИ B с A |
XRA C |
A9 |
Исключающее ИЛИ C с A |
XRA D |
AA |
Исключающее ИЛИ D с A |
XRA E |
AB |
Исключающее ИЛИ E с A |
XRA H |
AC |
Исключающее ИЛИ H с A |
XRA L |
AD |
Исключающее ИЛИ L с A |
XRA M |
AE |
Исключающее ИЛИ loc(HL) с A |
XRI d8 |
EE |
Исключающее ИЛИ d8 с A |
О выполнении некоторых команд i8080
Команды пересылки данных между регистрами кодируются в одном байте (это типичный случай регистровой адресации) следующим образом: 01DDDSSS , где DDD - номер регистра назначения; SSS - номер регистра приемника. Соответственно 01 - код операции пересылки. Никаких флагов команды пересылки не устанавливают. На выполнение команды тратится один машинный цикл.
Пересылка из ячейки памяти в регистр и из регистра в память осуществляется с помощью косвенно регистровой адресации. Это означает, что адрес ячейки памяти загружается в регистровую пару HL, а в командах типа MOV A,M (такие команды кодируются как 01DDD110) в регистр A будет загружено содержимое ячейки памяти, адрес которой содержится в HL. Так как в таких командах требуется обращение к памяти, то на их выполнение нужно два машинных цикла. Система команд процессора очень экономична - она не рассчитана на поддержку языков высокого уровня. Все это появится в Intel-процессорах позже.
Замечу, что средняя длина команды в типичной программе равна двум байтам, а для программ более поздних 16-разрядных процессоров типа 8086 она равна 4,1. Поэтому на логических программах 8-разрядные процессоры не сильно уступали 16-разрядным.
Аналогично работают и команды записи в память.
Команды непосредственной пересылки двухбайтные. В первом байте кодируются код операции и регистр, а второй содержит байт пересылаемых данных: 00DDD110 XXXXXXXX . Очевидно, что для исполнения команды требуется два цикла.
Более интересна версия этой команды MVI data, когда байт непосредственных данных пишется в память. Она кодируется так: 00110110 ХХХХХХХХ. Исполнение занимает три цикла.
Очень полезна группа команд LXI непосредственной загрузки регистровых пар непосредственным значением. Она позволяет одной командой переместить сразу два байта данных и широко используется программистами как в операциях адресной арифметики, так и при выполнении целочисленных вычислений. Команда кодируется так: 00RP0001 xxxxxxxx zzzzzzzz , где RP - регистровая пара; хххххххх - младший байт данных, zzzzzzzzz - старший байт данных.
При исполнении команды, требующей трех машинных циклов, старший байт данных грузится в старший регистр регистровой пары, а младший байт - в младший регистр. Название старшего регистра стоит в названии пары первым.
Команда прямой загрузки аккумулятора позволяет загрузить в него данные, на которые указывает адрес, содержащийся в самой команде.
Длина команды три байта. Кодируется она так: 001110010 хххххххх
zzzzzzzz
где xxxxxxxx - младшая часть адреса; zzzzzzzz - старшая часть адреса. Исполнение занимает машинных четыре цикла.
Симметричная по действию команда STA.
Команда LHLD addr (мнемоника расшифровывается Load H and L Direct) загружает в L содержимое ячейки памяти по адресу, кодируемому во втором и третьем байтах команды (т. е. адресация прямая). В H загружается байт из ячейки addr+1. Команда выполняется за пять машинных циклов. Обратная ей по действию команда SHLD (Store H and L Direct).
Команда LDAX reg (мнемоника от Load accumulator indirect). Содержимое ячейки памяти, адресуемой регистровой парой BC или DE, за два цикла загружается в аккумулятор.
Обратная по действию команда STAX reg.
Очень полезная команда XCHG. (H)<->(D), (L)<->(E). Выполняется за один цикл.
Начнем со сложения. Сложить аккумулятор с содержимым регистра ADD reg
Кодировка: 10000RRR Выполняется за один цикл. Обратите внимание, что все арифметические команды изменяют флаги: Z,S,P,CY,AC.
Для выполнения многобайтового сложения необходимо учитывать перенос. Поэтому младшие байты слагаемых складываются с помощью команды ADD, а все последующие в помощью команды ADC reg. Она учитывает при сложении содержимое флага переноса. Понятно, что в этой системе команд легко написать арифметику, которая будет работать с целыми числами длиной несколько килобайт (что и было сделано в системе muMATH-80).
Аналогично устроены команды вычитания.
Разновидностью команды сложения является команда инкремента регистра, необходимая для адресной арифметики и организации циклов.
INR reg
Кодировка: 00ККК100 Устанавливаются все флаги, за исключением CY.
Обратная по действию команда DCR reg.
Довольно редко используется команда DAA (мнемоника от Decimal Adjust Accumulator) выполняет следующие действия: если содержимое младшего полубайта (нибла) аккумулятора меньше 9 или установлен флаг CY, то (A) + 6, если значение старшего полубайта больше 9 или установлен флаг CY, то 6 добавляется к содержимому старшего полубайта.
При этом устанавливаются все флаги.
ANA reg
Флаг CY сбрасывается, а AC устанавливается (в 8085). В микропроцессоре 8080 на эти флаги влияет результат операции над третьими битами операндов.
В командах групп XRA и ORA флаги CY и AC сбрасываются.
CMP reg - сравнить регистр (Compare register), вычитает содержимое регистра из аккумулятора. Содержимое аккумулятора не изменяется. Флаги устанавливаются как при вычитании. Z=1, если (A) = (reg). CR = 1, если (A) < (reg).
Циклический сдвиг влево RCL работает следующим образом. Содержимое аккумулятора сдвигается на одну позицию влево, т. е. каждый старший бит получает значение стоящего рядом с ним младшего бита. Содержимое седьмого бита переходит в нулевой бит аккумулятора:
(CY) <-(b7).
RRC - сдвигает содержимое
аккумулятора вправо. (CY)<-
{b0}, (b7)<-(b0).
RAL - (Rotate Left trough Carry). Сначала (CY) заносится в младший бит аккумулятора, а потом в CY записывается содержимое старшего его бита.
Формально: (b0)<-(CY), (CY)<-(b7).
Аналогично со сдвигом вправо: (Bn)<-(Bn+1), (CY)<-(b0), (b7)<-(CY).
Команда CMA (мнемоника от Complement Accumulator) инвертирует каждый бит аккумулятора, т. е. 0 становится 1 и наоборот. Флаги не устанавливаются.
Команда CMC инвертирует содержимое флага переноса. Другие флаги не устанавливаются.
По командам управления стоит отметить выполнение команды вызова подпрограммы.
CALL addr - при ее выполнении в стек записывается адрес следующей за CALL команды, значение указателя стека дважды декрементируется, а управление передается по указанному адресу.
Команда возврата из подпрограммы записывает в счетчик команд адрес из вершины стека, увеличивает указатель стека на 2 и передает управление на новый адрес. Поэтому если модифицировать адрес возврата в стеке, то можно перейти совсем в другое место.
Для этого есть, впрочем, более удобная возможность - команда PCHL. Она позволяет передать управление по адресу в регистровой паре HL.
Иногда в системных программах используется команда останова HLT. Процессор останавливается, регистры и флаги не устанавливаются. Для запуска важно подать сигнал Reset.
IN port - данные из порта с указанным номером считываются в аккумулятор. Циклов 3. Флаги не изменяются.
OUT port - содержимое аккумулятора помещается на шину данных для записи в указанный в команде порт.
28 января 2006 г.