33. Программирование CPU
33. Программирование CPU
🎯 Цель урокаНаучиться загружать программы в память и выполнять их на собранном процессоре.
🧠 Теория (10 мин)
Как программа попадает в CPU?
1. Написать программу (ассемблер)
2. Транслировать в машинный код
3. Загрузить в RAM
4. Сбросить PC в 0
5. Запустить тактовый генератор
Память программ
В простейшем случае — DIP-переключатели или EEPROM:
Адрес 0: [SW][SW][SW][SW][SW][SW][SW][SW] = 0x1E (LDA 14)
Адрес 1: [SW][SW][SW][SW][SW][SW][SW][SW] = 0x2F (ADD 15)
Адрес 2: [SW][SW][SW][SW][SW][SW][SW][SW] = 0xD0 (OUT)
...
🔧 Варианты памяти программ
Вариант 1: DIP-переключатели
Для 16 байт RAM:
- 16 × 8-позиционных DIP = 128 переключателей 😱
Хорошо для отладки, плохо для реальных программ.
Вариант 2: EEPROM (AT28C16)
AT28C16 — 2K × 8 EEPROM
Программируется с помощью T48 программатора!
┌───────────────────┐
│ AT28C16 │
│ │
│ A0-A10 ◄── адрес │
│ D0-D7 ──► данные │
│ ~CE, ~OE │
└───────────────────┘
Вариант 3: Ручной ввод через кнопки
[Адрес: 4-bit DIP] [Данные: 8-bit DIP] [WRITE кнопка]
Процедура:
1. Установить адрес
2. Установить данные
3. Нажать WRITE
4. Повторить для следующего адреса
📋 Практика: Загрузка программы
Программа: Счёт 0-5
; Считать от 0 до 5 и остановиться
0: LDI 0 ; 50 — A = 0
1: OUT ; D0 — вывести
2: ADD 15 ; 2F — A += 1
3: SUB 14 ; 3E — A -= 6 (сравнение)
4: JZ 7 ; 87 — если 0, конец
5: ADD 14 ; 2E — A += 6 (восстановить)
6: JMP 1 ; 61 — повтор
7: HLT ; F0 — стоп
; Данные:
14: 06 ; число 6
15: 01 ; шаг 1
Машинный код
| Адрес | Hex | Двоичный |
|---|---|---|
| 0 | 50 | 0101 0000 |
| 1 | D0 | 1101 0000 |
| 2 | 2F | 0010 1111 |
| 3 | 3E | 0011 1110 |
| 4 | 87 | 1000 0111 |
| 5 | 2E | 0010 1110 |
| 6 | 61 | 0110 0001 |
| 7 | F0 | 1111 0000 |
| … | ||
| 14 | 06 | 0000 0110 |
| 15 | 01 | 0000 0001 |
🔬 Пошаговое выполнение
Отладка: режим Single-Step
CLK: ручной (кнопка) vs автоматический (555)
В режиме single-step:
1. Нажал кнопку → один такт
2. Посмотрел состояние (PC, A, FLAGS, BUS)
3. Нажал снова → следующий такт
Трассировка выполнения
| Такт | PC | IR | A | Шина | Действие |
|---|---|---|---|---|---|
| 0 | 0 | – | XX | 50 | Fetch: IR=50 |
| 1 | 1 | 50 | 00 | – | LDI 0: A=0 |
| 2 | 1 | – | 00 | D0 | Fetch: IR=D0 |
| 3 | 2 | D0 | 00 | 00 | OUT: display=0 |
| 4 | 2 | – | 00 | 2F | Fetch: IR=2F |
| 5 | 3 | 2F | 01 | 01 | ADD 15: A=0+1=1 |
| … |
💡 Инструменты программирования
Ассемблер на Python
# Простейший ассемблер для SAP-1
opcodes = {
'NOP': 0x0, 'LDA': 0x1, 'ADD': 0x2, 'SUB': 0x3,
'STA': 0x4, 'LDI': 0x5, 'JMP': 0x6, 'JC': 0x7,
'JZ': 0x8, 'AND': 0x9, 'OR': 0xA, 'XOR': 0xB,
'NOT': 0xC, 'OUT': 0xD, 'INP': 0xE, 'HLT': 0xF
}
def assemble(line):
parts = line.upper().split()
if not parts:
return None
mnemonic = parts[0]
operand = int(parts[1]) if len(parts) > 1 else 0
return (opcodes[mnemonic] << 4) | (operand & 0xF)
# Пример:
program = [
"LDI 0",
"OUT",
"ADD 15",
"JMP 1",
]
for addr, line in enumerate(program):
code = assemble(line)
print(f"{addr:2d}: {code:02X} ; {line}")
Вывод:
0: 50 ; LDI 0
1: D0 ; OUT
2: 2F ; ADD 15
3: 61 ; JMP 1
📝 Программы для практики
Программа 1: Фибоначчи
; Вычислить числа Фибоначчи: 1, 1, 2, 3, 5, 8...
0: LDI 1 ; A = 1 (первое число)
1: STA 14 ; F1 = 1
2: STA 15 ; F2 = 1
3: OUT ; Вывести F2
4: ADD 14 ; A = F2 + F1
5: STA 14 ; Сохранить в F1 (было F2)
... (обмен F1 ↔ F2)
Программа 2: Бегущий огонь
; Бит сдвигается: 1, 2, 4, 8, 16...
0: LDI 1 ; A = 00000001
1: OUT ; Вывести
2: ADD 15 ; A = A + A (сдвиг влево!)
3: JC 0 ; Если переполнение, начать сначала
4: JMP 1 ; Иначе повтор
15: (data) = копия A (для удвоения)
Программа 3: Детектор простых чисел
; Проверить, является ли N простым
; (упрощённо: проверка делимости на 2 и 3)
Сложно для 4-бит адресации!
Но показывает пределы простой архитектуры.
🔧 Загрузка через T48
Если используем EEPROM:
- Написать программу в hex-файл
- Подключить AT28C16 к T48
- Записать hex-файл в EEPROM
- Установить EEPROM в панельку на плате CPU
- Запустить!
Intel HEX формат:
:10000000501F2FD061F00000000000000000000032
:00000001FF
📝 Мини-задания
✅ Чеклист
- Могу транслировать программу в hex
- Понимаю пошаговое выполнение
- Могу загрузить программу в память
- Отладил программу в single-step режиме
