От простого сложения к управляемым операциям
В предыдущих частях мы заложили основу «Контрольной секции». Теперь настало время собрать всё воедино и реализовать первую полезную операцию — сложение содержимого регистров R0 и R1, которое мы рассматривали ранее.
Для этого необходимо соединить выходы 4, 5 и 6 степпера (устройства, задающего последовательность тактов) с управляющими входами регистров, как показано на схеме. Эта манипуляция позволяет на каждом из этих шагов активировать один бит разрешения на выход ('e') в левой части схемы и один бит разрешения на запись ('s') в правой. Таким образом, данные по шине передаются из одного регистра в другой в строго определённой последовательности.
Давайте детально разберём этот процесс. На шаге 4 активируется выход регистра R1 ('e') и вход временного регистра TMP ('s'). Данные из R1 копируются в TMP. На шаге 5 включается выход R0 ('e') и вход аккумулятора ACC ('s'), в результате чего число из R0 передаётся в ACC. На этом этапе нам не нужно задавать код операции (op-код) для арифметико-логического устройства (АЛУ), так как код сложения (ADD) по умолчанию равен 000. Для других операций пришлось бы выставить соответствующие биты 'op'. Наконец, на шаге 6 активируется выход ACC ('e') и вход R0 ('s'), что приводит к записи результата из аккумулятора обратно в регистр R0. Наглядная временная диаграмма этих сигналов представлена ниже.
В итоге регистр R0 теперь содержит сумму исходных значений из R0 и R1. Именно так, шаг за шагом, выполняются элементарные операции внутри процессора.
Однако есть проблема: после шага 7 степпер сбрасывается и цикл повторяется с начала. На шаге 6 снова будет вычислена сумма R0 и R1, и так до бесконечности. Учитывая, что тактовая частота процессора измеряется миллионами герц, а наши регистры 8-битные, значение в R0 очень быстро достигнет максимума (255), после чего вычисления потеряют смысл.
Расширяем возможности: работа с памятью
Теперь рассмотрим более полезную операцию — сохранение данных из регистра в оперативную память (RAM). Предположим, нам нужно переместить число из R0 в ячейку RAM, адрес которой хранится в R2. Схема для этой операции ещё проще.
Здесь требуется всего два шага! На шаге 1 активируются выход R2 ('e') и вход регистра адреса памяти MAR ('s'), тем самым в MAR загружается адрес для обращения к RAM. На шаге 2 включаются выход R0 ('e') и управляющий вход RAM на запись ('s'), что приводит к копированию данных из R0 в указанную ячейку памяти.
Таким образом, мы можем выполнять множество действий: копировать данные, производить арифметические операции через АЛУ, сравнивать значения и т.д. Но ключевая проблема остаётся: любая операция будет бесконечно повторяться в цикле. Нам необходим механизм, который позволит выполнять одну инструкцию, затем другую, третью — то есть управлять последовательностью действий. Нужно научить контрольную секцию «понимать», какие соединения активировать после каждого сброса степпера.
Аналогия с программируемым автоматом
Чтобы понять, как решить эту задачу, проведём аналогию. Представьте автоматизацию работы кассира в фастфуде. Его работа — это последовательность простых действий: поприветствовать клиента, принять заказ, нажать соответствующие кнопки на кассе, принять оплату, собрать заказ.
Допустим, у кассира есть 256 возможных элементарных действий. Каждому можно присвоить уникальный 8-битный код (байт). Тогда весь алгоритм его работы можно представить как последовательность таких байтов-инструкций. Например:
0000 0000 = Подойти к стойке
0000 0001 = Спросить: «Могу я принять ваш заказ?»
0000 0010 = Слушать ответ
0000 0011 = Нажать кнопку «бургер»
... и так далее.
Кроме простых действий, нам понадобятся инструкции для управления ходом программы, например, условные переходы (если клиент сказал «бургер», перейти к шагу добавления бургера) и безусловные переходы (вернуться к началу для обслуживания следующего клиента). Описав весь процесс таким набором инструкций, мы, по сути, создали программу для нашего «кассира-автомата». Именно так и работают программы в компьютере.
Ключевое изобретение: система команд и счётчик инструкций
Жёсткая коммутация проводами даёт лишь одну повторяющуюся операцию. Решение — соединить все управляющие входы регистров и АЛУ со степпером не напрямую, а через логические элементы, управляемые специальным кодом. Но как выбирать этот код?
Великое изобретение заключается в следующем: инструкции будут храниться в оперативной памяти (RAM) в виде последовательности байтов, а процессор будет поочерёдно считывать и выполнять их. Для реализации этой идеи нужны три новых компонента:
- Регистр инструкций (IR — Instruction Register): в него загружается байт-команда из памяти. Биты этого регистра будут управлять логикой контрольной секции, определяя, какую операцию выполнять на шагах 4-6.
- Регистр-счётчик адреса инструкций (IAR — Instruction Address Register): хранит адрес в RAM, по которому находится следующая команда для выполнения. После выполнения каждой инструкции его значение увеличивается, чтобы перейти к следующей.
- Специальная логика в секции управления: обеспечивает цикл «выборка-выполнение». Она загружает команду из RAM (по адресу из IAR) в IR, увеличивает IAR на 1 и выполняет команду из IR. После выполнения степпер сбрасывается, и цикл повторяется для следующей инструкции.
Именно этот механизм превращает набор транзисторов в программируемое устройство. Последовательность байтов-инструкций в памяти и есть программа.
На схеме показан процессор с добавленными регистрами IR и IAR. У IAR, как и у обычных регистров, есть вход ('s') и выход ('e'). У IR же есть только вход ('s'), так как его выход не подключён к шине данных — он управляет только логикой секции управления.
Цикл «выборка-выполнение»
Работа процессора теперь представляет собой непрерывный цикл. Первые три шага степпера отведены под выборку (fetch) инструкции, последующие три — под её выполнение (execute).
Рассмотрим фазу выборки подробнее:
Шаг 1 (сложный): Происходят две операции параллельно. Во-первых, значение из IAR (адрес следующей команды) копируется в MAR (регистр адреса памяти). Во-вторых, АЛУ, которому ещё не задана операция (по умолчанию ADD — сложение), прибавляет к значению в шине (это IAR) константу 1 (подаётся через специальную линию BUS1) и записывает результат (IAR+1) в аккумулятор ACC.
Шаг 2: Активируется чтение из RAM по адресу в MAR. Считанный байт (инструкция) помещается в шину и записывается в регистр IR.
Шаг 3: Значение «IAR+1», которое было вычислено на шаге 1 и хранится в ACC, переписывается обратно в IAR. Теперь IAR указывает на следующую ячейку памяти для будущей инструкции.
После этого на шагах 4, 5 и 6 выполняется инструкция, биты которой сейчас находятся в IR. По завершении шага 6, на шаге 7 степпер сбрасывается, и цикл начинается заново, но уже со следующим адресом команды в IAR.
Проектирование системы команд
8-битный регистр IR теоретически позволяет закодировать до 256 различных инструкций. Для нашего учебного процессора разработаем девять, которых будет достаточно для базовых операций: перемещения данных и работы с АЛУ.
Арифметико-логические инструкции
Это самый мощный класс команд. Наше АЛУ поддерживает 8 операций (ADD, SUB, AND, OR, XOR, NOT, SHL, SHR, CMP). Инструкция должна указать, какую операцию выполнить и с какими двумя регистрами (их у нас четыре: R0, R1, R2, R3).
Формат такой инструкции:
Бит 0: Всегда '1', признак команды АЛУ.
Биты 1-3: Код операции АЛУ (3 бита = 8 вариантов).
Биты 4-5: Номер первого регистра-источника (Reg A).
Биты 6-7: Номер второго регистра-приёмника (Reg B).
Например, код 1000 0110 означает: выполнить операцию ADD (000) над регистрами R1 (01) и R2 (10), результат поместить в R2.
Для реализации выбора произвольного регистра (а не только жёстко заданных R0 и R1) в контрольной секции используются дешифраторы и логические элементы И. Дешифратор, управляемый битами 4-5 из IR, активирует выход только одного из четырёх регистров в нужный момент времени (например, на шаге 5 для Reg A).
Схема выполнения команды АЛУ, например, ADD R1, R2, выглядит так:
Шаг 4: Содержимое Reg B (R2) копируется во временный регистр TMP.
Шаг 5: Содержимое Reg A (R1) помещается на шину. АЛУ получает два числа (из TMP и шины) и код операции из IR. Результат вычисления записывается в ACC.
Шаг 6: Результат из ACC копируется обратно в Reg B (R2).
Исключение — операция сравнения CMP, которая лишь устанавливает флаги, но не сохраняет результат в регистр.
Рождение языка ассемблера
Запоминать и записывать программы в виде двоичных кодов, вроде 1000 0110, неудобно. На помощь приходит символическое представление — язык ассемблера. Для наших инструкций АЛУ он будет выглядеть так:
Теперь команда ADD R1, R2 интуитивно понятна. Программист пишет код на ассемблере, а специальная программа-ассемблер переводит его в двоичные коды инструкций, которые уже можно загрузить в память компьютера для выполнения.
#компьютеры #наука и техника #образование #начинающим радиолюбителям #электроника начинающим #процессоры
Часть 7 - Назад Далее - Часть 9
Еще по теме здесь: Новости науки и техники.
Источник: Как устроен компьютер? Часть 8 (Как работают инструкции).