Русский      English

Мiкропроцесор 8080
Едуард Пройдаков

Так склалося, що мiкропроцесор Intel 8080, що з'явився на свiт божий 1 квiтня 1974 р., зiграв дуже велику роль на визначеному етапi розвитку ОТ у СРСР. Причин тому було трохи: на вiдмiну вiд досить твердої архiтектури 16-розрядного мiкропроцесора LSI 11, що йшла вiд мiнiкомпютерiв, 8-розрядний 8080 був дивно простий. Студенти старших курсiв Фiзтеха, що проходили практику в мене в лабораторiї в iнститутi проблем керування (IПК), збирали на ньому одноплатнi комп'ютери в себе в гуртожитку. З елементною базою в лабораторiї завжди було непогано, i ми навiть заохочували подiбнi речi - так студент швидше починав розумiти, що до чого.

На цьому процесорi, i його аналогах, сумiсних з ним, були зробленi такi мiкро-ЕОМ:

Єдиний iстотний недолiк - процесор вимагав трьох рiвнiв напруги живлення.

Система команд 8080 нараховувала 79 iнструкцiй (см. Довiдник по системi команд мiкропроцесора Intel 8080).

Київське НВО "Кристал" в кiнцi 70-х рокiв випустило мiкропроцесорний комплект К580, в який входили наступнi мiкросхеми:

На жаль, у мене описи цих мiкросхем не збереглися, тому буду вдячний усiм, хто надiшле опис програмування зазначених БIС.

Вiдзначу, що в корпорацiї Intel для 8080/85 випускалася мiкросхема арифметичного прискорювача. Однак тому що 8080 складав реальну погрозу просуваємому Мепом мiкропроцесору "Електронiка-60", те ця мiкросхема в СРСР нiколи не вiдтворювалася.


Лiтература:

  1. Озерецковский С. К 25-летию первого микропроцессора Intel.
    http://www.ritmpress.ru/it/press/cwm/41_96/list.htm.
  2. Эмулятор компьютера Радио-РК.
    http://www.members.tripod.com/~barsuk.
  3. Сайт Николая Жеведя, посвященный истории компьютера ОРИОН-128 (конструкция опубликована в первом номере журнале "Радио" за 1990 г.)
    http://orion128.nm.ru/.
  4. Справочник по микропроцессорам.
    http://www.microprocessor.sscc.ru/chiplist.

Архитектура процессора 8080

   
 
Регiстровий файл
 

Тому що адресний простiр всього 64 Кб, то повна адреса займає 2 байти. Команди цього процесора бувають одно-, двох- i трьохбайтними. У першому байтi завжди мiститься код операцiї. Єдиний iстотний недолiк - процесор вимагав трьох рiвнiв напруги живлення.

Довiдник по системi команд мiкропроцесора Intel 8080

Команди цього процесора бувають одне-, двох- i трьохбайтними. У першому байтi завжди мiститься код операцiї.

Позначення.

A, B, ..., L - назва 8-розрядних регiстрiв.

BC, DE, HL - назва регiстрових пар, що утворять 16-розряднi регiстри.

SP - 16-розрядний покажчик стеку.

PSW - слово стану програми, мiстить регiстр прапорiв.

a16 - двобайтова адреса.

d8 - байт безпосереднiх даних.

d16 - два байти безпосереднiх даних.

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 вправо на один разряд с переносом
RIM 20 Считать маску прерывания (в 8085)
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
SIM 30 Установить маску прерывания (только в 8085)  
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

Команди пересилання даних мiж регiстрами кодуються в одному байтi (це типовий випадок реєстрової адресацiї) у такий спосiб:

01DDDSSSгде DDD - номер регiстру призначення; SSS - номер регiстру приймача. Вiдповiдно 01 - код операцiї пересилки. Нiяких флагiв команди пересилання не встановлюють. На виконання команди витрачається один машинний цикл.

Пересилання з комiрки пам'ятi в регiстр i з регiстра в пам'ять здiйснюються за допомогою побiчно реєстрової адресацiї. Це означає, що адреса комiрки пам'ятi завантажується в реєстрову пару HL, а в командах типу MOV A,M (такi команди кодуються як 01DDD110) у регiстрA буде завантажений вмiст комiрки пам'ятi, адреса якого мiститься в HL. Тому що в таких командах потрiбно звертання до пам'ятi, то на їхнє виконання потрiбно два машинних цикли. Система команд процесора дуже економiчна - вона не розрахована на пiдтримку мов високого рiвня. Усе це з'явиться в Intel-процесорах пiзнiше.

Зауважу, що середня довжина команди в типовiй програмi дорiвнює двом байтам, а для програм бiльш пiзнiх 16-розрядних процесорiв типу 8086 вона дорiвнює 4,1. Тому на логiчних програмах 8-розряднi процесори не сильно поступалися 16-розрядним.

Аналогiчно працюють i команди запису в пам'ять.

Команди безпосереднього пересилання двубайтовi. У першому байтi кодуються код операцiї i регiстр, а другий мiстить байт даних, що пересилається:

00DDD110 XXXXXXXXОчевидно, що для виконання команди потрiбно два цикли.

Бiльш цiкава версiя цiєї команди MVI data, коли байт безпосереднiх даних пишеться в пам'ять.MVI data, коли байт безпосереднiх даних пишеться в пам'ять.

Вона кодується так:

00110110 ХХХХХХХХВиконання займає три цикла.

Дуже корисна група командLXIбезпосереднього завантаження реєстрових пар безпосереднiм значенням. Вона дозволяє однiєю командою перемiстити вiдразу два байти даних i широко використовується програмiстами як в операцiях адресної арифметики, так i при виконаннi цiлочисельних обчислень.

Команда кодується так:

00RP0001 xxxxxxxx zzzzzzzz где RP - регiстрова пара; хххххххх - молодший байт даних, zzzzzzzzz - старший байт даних.

При виконаннi команди, що вимагає трьох машинних циклiв, старший байт даних вантажиться в старший регiстр реєстрової пари, а молодший байт - у молодший регiстр. Назва старшого регiстра стоїть в назвi пари першою.

Команда прямого завантаження акумулятора дозволяє завантажити в нього данi, на якi вказує адреса, що мiститься в самiй командi.

Довжина команди три байта. Кодується она так:

001110010 хххххххх zzzzzzzz де xxxxxxxx - молодша частина адреси; zzzzzzzz - старша частина адреси.

Виконання займає машинних чотири цикли.

Симетрична по дiї команда STA.

Команда LHLD addr (мнемонiка розшифровується Load H and L Direct) завантажує в L вмiст комiрки пам'ятi за адресою, кодуємому в другому i третьому байтах команди (тобто адресацiя пряма). В H завантажується байт з комiрки addr+1.

Команда виконується за п'ять машинних циклiв. Зворотна їй по дiї командаSHLD (Store H and L Direct).

Команда LDAX reg (мнемонiка от Load accumulator indirect). Вмiст комiрки пам'ятi, адресуємої реєстровою парою BC чи DE, за два цикли завантажується в акумулятор.

Зворотна по дiї команда STAX reg.

Дуже корисна команда XCHG. (H)<->(D), (L)<->(E). Виконується за один цикл.

Арифметичнi команди

Почнемо з додавання. Скласти акумулятор iз вмiстом регiстра ADD reg

Кодування: 10000RRR

Виконується за один цикл. Звернiть увагу, що всi арифметичнi команди змiнюють флаги: Z,S,P,CY,AC.

Для виконання багатобайтового додавання необхiдно враховувати перенос. Тому молодшi байти доданкiв складаються за допомогою команди ADD, а всi наступнi за допомогою команди ADC reg. Вона враховує при додаваннi вмiст флагу переносу. Зрозумiло, що в цiй системi команд легко написати арифметику, що буде працювати з цiлими числами довжиною декiлька кiлобайт (що i було зроблено в системi muMATH-80).

Аналогiчно улаштованi команди вирахування.

Рiзновидом команди додавання є команда iнкремента регiстра, необхiдна для адресної арифметики й органiзацiї циклiв.

INR reg
Кодування: 00ККК100

Установлюються всi флаги, за винятком CY.

Зворотна по дiї командаDCR reg.

Досить рiдко використовується командаDAA (мнемонiка от Decimal Adjust Accumulator) виконує наступнi дiї: якщо вмiст молодшого напiвбайта (нибла) акумулятора менше 9 чи встановлений флаг CY, то (A) + 6, якщо значення старшого напiвбайта бiльше 9 чи встановлений флаг CY, то 6 додається до вмiсту старшого напiвбайта.

При цьому установлюються всi флаги.

Логiчнi команди

ANA reg
Флаг CY знiмається, а AC встановлюється (в 8085). У мiкропроцесорi 8080 на цi флаги впливає результат операцiї над третiми бiтами операндiв.

В командах груп XRA i ORA флаги CY та AC знiмаються.

CMP reg - порiвняти регiстр (Compare register), вiднiмає вмiст регiстра з акумулятора. Вмiст акумулятора не змiнюється. Флаги встановлюються як при вирахуваннi. Z=1, якщо (A) = (reg). CR = 1, якщо (A) < (reg) CR = 1, если (A) < (reg).

Циклiчне зрушення влiво RCL працює в такий спосiб. Вмiст акумулятора зрушується на одну позицiю влiво, тобто кожен старший бiт одержує значення молодшого бiта, що стоїть поруч з ним. Вмiст сьомого бiта переходить у нульовий бiт акумулятора:

(CY) <-(b7).

RRC - зрушує вмiст акумулятора вправо. (CY)<- {b0}, (b7)<-(b0).

RAL - (Rotate Left trough Carry). Спочатку (CY) заноситься в молодший бiт акумулятора, а потiм в CY записується вмiст старшого його бiта.

Формально: (b0)<-(CY), (CY)<-(b7).

Аналогiчно зi зрушенням вправо: (Bn)<-(Bn+1), (CY)<-(b0), (b7)<-(CY).

Команда CMA (мнемонiка вiд Complement Accumulator) iнвертує кожен бiт акумулятора, тобто 0 стає 1 i навпаки. Флаги не встановлюються.

Команда CMC iнвертує вмiст флагу переносу. Iншi флаги не встановлюються.

По командах керування варто вiдзначити виконання команди виклику пiдпрограми.

CALL addr - при її виконаннi в стек записується адреса наступної за CALL команди, значення покажчика стека двiчi декрементується, а керування передається по зазначенiй адресi.

Команда повернення з пiдпрограми записує в лiчильник команд адресу з вершини стека, збiльшує покажчик стека на 2 i передає керування на нову адресу. Тому якщо модифiкувати адресу повернення в стецi, то можна перейти зовсiм в iнше мiсце.

Для цього є, утiм, бiльш зручна можливiсть - команда PCHL. Вона дозволяє передати керування за адресою в реєстровiй парi HL.

Iнодi в системних програмах використовується команда зупинки HLT. Процесор зупиняється, регiстри i флаги не встановлюються. Для запуску важливо подати сигнал Reset.

IN port - данi з порту з зазначеним номером зчитуються в акумулятор. Циклiв 3. Флаги не змiнюються.

OUT port - вмiст акумулятора мiститься на шину даних для запису в зазначений у командi порт.

Як бачимо, система команд проста i невигадлива. Її легко освоювали навiть електронщики. Написано безлiч емуляторiв системи 8080, 8085 i Z-80 для PC, а також навчальних програм для студентiв.

Звичайно, через двадцять рокiв можна i Бейсiк забути. Тому, можливо, якiсь моменти я пропустив. Буду щиро вдячний усiм надiславшим на адресу chief@pcweek.ru свої доповнення i зауваження, приклади навчальних програм i т.п.


Переклад з росiйської Малашок Т.I.
Матерiали опублiкованi з дозволу редакцiї сайту "Виртуальный компьютерный музей"
Хронологiя розвитку обчислювальної технiки в Українi