Сказ о том, как я эмулятор Intel 4004 на Python писал

febb8008ffa7f030b9ba9fb2432658fb.png

Вступление

С началом учебного года в мой техникум пришла такая штука, как Код будущего. Я и пара моих приятелей решили записаться на курсы по программированию на Python, но этот процесс длился очень долго, к сожалению так ничего и не началось :(Из-за двух каких-то, извиняюсь за выражение, дебилов, которые что-то и где-то не успели вовремя заполнить и сдать, пришлось свернуть эту программу в моём техникуме. Я не особо расстроился, наоборот, это даже дало мне хороший толчок для изучения данного языка программирования самостоятельно дома, как я и делал со всеми предыдущими языками :) Изучив достаточно материала, я осмелился на написание эмулятора CPU, конкретно Intel 4004 (дедушку современных микропроцессоров) с очень урезанным функционалом.

Как всё писалось?

Перед началом я прочитал различные статьи, документации, смотрел видео на YouTube и тем самым получил необходимый минимум знаний о том, как работает CPU.

Начал я с реализации памяти, в которую будут записываться результаты программ:

memory = bytearray(256) # 256 байт памяти

Затем я создал класс I4004, в который стал добавлять функции. Первой стала функция инициализации:

def __init__(self, program, memory):
        self.program = program
        self.memory = memory

        self.acc = 0 # Аккумулятор
        self.pc = 0 # Счётчик команд

Имеется Аккумулятор (acc) — регистр процессора, в котором сохраняются результаты выполнения арифметических и логических команд, а также Счётчик команд (pc) — регистр процессора, который указывает, какую команду нужно выполнять следующей.

Следующей стала функция run, которая отвечала за запуск:

def run(self):
        while True:
            opcode = self.program[self.pc]

            if opcode == 0x00: # Остановка
                return

            elif opcode == 0xA2: # Загрузка числа в аккумулятор
                self.acc = self.program[self.pc + 1]
                self.pc += 2

            elif opcode == 0xA4: # Загрузка числа в регистр B
                self.rB = self.program[self.pc + 1]
                self.pc += 2

            elif opcode == 0x58: # Сложение
                self.acc += self.rB
                self.pc += 1
                if self.acc > 15:
                    self.acc = 15
                    print("")

            elif opcode == 0x29: # Вычитание
                self.acc -= self.rB
                self.pc += 1
                if self.acc < 0:
                    self.acc = 0
                    print("Вы не можете получить число выше 15!")

            # и так далее...

            else:
                print("Неизвестная инструкция!")
                return

Для составления программ используется опкод — часть машинного языка, называемая инструкцией и определяющая операцию, которая должна быть выполнена. Вот таблица опкодов и соответствующая им операция:

Опкод

Операция

0×00

Остановка программы

0xA2

Загрузка числа в аккумулятор

0xA4

Загрузка числа в регистр B

0×58

Сложение

0×29

Вычитание

0×16

Логическая операция И 

0×08

Логическая операция ИЛИ 

0xD0

Сохранение результата в памяти

Как составляется программа?

Программу надо составлять прямо в коде, а конкретно в program.py. Вот пример программы сложения чисел 5 и 3:

program = [   
    0xA2, 0x05,
    0xA4, 0x03,
    0x58,
    0xD0, 0x10,
    0x00,
]

Заключение

Надеюсь, что кому-нибудь эта статья станет полезной, возможно она подтолкнёт кого-то на написание чего-то похожего.

Полный код можно посмотреть на моём GitHub.

С вами был Yura_FX. Спасибо, что дочитали данную статью до конца. Не забывайте делиться своим мнением в комментариях :)

© Habrahabr.ru