Русский      English

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

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

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

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

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

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

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

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


Література:

  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

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

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

Довідник по системі команд мікропроцесора 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 вправо на один разряд с переносом
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

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

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

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

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

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

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

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

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

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

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

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

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

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 regіster), віднімає вміст регістра з акумулятора. Вміст акумулятора не змінюється. Флаги встановлюються як при вирахуванні. Z=1, якщо (A) = (reg). CR = 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 - вміст акумулятора міститься на шину даних для запису в зазначений у команді порт.

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

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


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