Как устроен компьютер? Часть 8 (Как работают инструкции)

И снова что-то полезное

Теперь, когда положено начало «Контрольной секции», мы можем соединить несколько проводов и сделать простое сложение R0 и R1, которое было рассмотрено ранее.

Соединить провода нужно с выходами 4, 5 и 6 Степпера, как показано на рисунке выше. Данная манипуляция позволяет каждым из этих шагов включать один бит ‘e’ в левой части и один бит ‘s’ в правой одновременно, тем самым передавая данные по шине из одного регистра в другой в определенной последовательности.

Рассмотрим теперь подробнее, что тут происходит. Шаг 4: выставляется ‘e’ регистра R1 и ‘s’ регистра TMP. Таким образом, данные из R1 копируются в TMP. Шаг 5: выставляется бит ‘e’ регистра R0 и ‘s’ регистра ACC. Теперь происходит копирование данных из R1 в ACC. В данном случае биты ‘op’ ALU выставлять не нужно, так как оп-код сложения (ADD) у нас равен 000. Но если бы мы производили другую операцию, то нужно бы было еще выставить 'op' биты для ALU соответствующим образом. Шаг 6: выставляется бит ‘e’ ACC и бит ‘s’ R0. Теперь происходит копирование данных из ACC в R0. Ниже приведен наглядный график включения всех этих сигналов.

Теперь R0 содержит сумму исходных данных R0 и R1. Именно таким образом и производятся операции внутри процессора.

После шага 7, все повторится сначала: Степпер дойдет до шага 4, и на шаге 6 мы снова получим сумму R0 и R1. И так – бесконечно. Учитывая, что тактовая частота процессора составляет миллионы тактов в секунду, а регистры у нас 8-ми битные, можно понять, что R0 очень быстро достигнет значения 255. Такие вычисления для нас уже не очень-то и полезны.

Теперь давайте представим, что нам нужно переместить данные из регистра R0 в регистр RAM по адресу, записанному в R2. Взгляните на схему ниже.

Здесь все даже проще – всего два шага! Шаг 1: выставлены ‘e’ R2 и ‘s’ MAR, таким образом, указывается адрес ОЗУ. Шаг 2: выставлены ‘e’ R0 и ‘s’ RAM, теперь данные из R0 скопированы в ОЗУ в адрес R2.

Так мы можем осуществлять любые из доступных действий с данными: копировать, сравнивать, производить арифметические действия с помощью АЛУ и т.д. Но любое действие так же будет бесконечно повторяться. Поэтому нам нужно как-то заставить процессор делать одно действие один раз, затем делать какое-то другое действие и т.д. Нужно как-то сообщать контрольной секции, что с чем соединять каждый раз после обновления Степпера.

Что дальше?

В продолжение мысли, сказанной в конце предыдущей главы. Представим себе, как были созданы терминалы в ресторанах быстрого питания. Кому-то пришла в голову идея о замене кассира компьютером. Ведь кассир, по сути, выполняет одни и те же простые действия в определенном порядке. Компьютер ведь работает так же!

И так, какие же это действия? Подойти к стойке, спросить «Могу я принять Ваш заказ?», прослушать ответ, нажать кнопку «Бургер» на кассе и т.д.

Теперь представим, что у кассира фастфуда есть до 256 различных действий. Каждому из этих действий можно присвоить отдельное состояние байта. Теперь нам нужно разработать некий код для каждого состояния байта действия сотрудника. В таком случае последовательность действий можно будет выразить как последовательность определенных байтов:

0000 0000 = Подойти к стойке

0000 0001 = Сказать: «Могу я принять Ваш заказ, мой господин?»

0000 0010 = Прослушать ответ

0000 0011 = Нажать кнопку «бургер»

0000 0100 = Нажать кнопку «картошка»

0000 0101 = Нажать кнопку «кола»

0000 0110 = Нажать кнопку «итого»

0000 0111 = Взять деньги

0000 1000 = Выдать сдачу

0000 1001 = Открыть пакет

0000 1010 = Положить бургер в пакет

0000 1011 = Положить картошку в пакет

0000 1100 = Положить колу в пакет

0000 1101 = Выдать пакет покупателю

1000 0000 = Перейти к строке «номер».

0100 0000 = Если «Да» перейти к строке «номер»

0001 0000 = Пойти домой

Теперь мы можем полностью описать весь алгоритм работы кассира:

1. 0000 0000 = Подойти к стойке

2. 0000 0001 = Сказать: «Могу я принять Ваш заказ, мой господин?»

3. 0100 0010 = Если покупатель молчит, перейти к шагу 2

4. 0000 0010 = Прослушать ответ

5. 0100 0111 = Если покупатель не говорит «бургер»,

перейти к шагу 7

6. 0000 0011 = Нажать кнопку «бургер» на кассе.

7. 0100 1001 = Если покупатель не говорит «картошка»,

перейти к шагу 9

8. 0000 0100 = Нажать кнопку «картошка» на кассе

9. 0100 1011 = Если покупатель не говорит «кола»,

перейти к шагу 11

10. 0000 0101 = Нажать кнопку «кола» на кассе

11. 0100 1101 = Если покупатель сказал «Это все», перейти к шагу 13

12. 1000 0100 = Перейти к шагу 4

13. 0000 0110 = Нажать кнопку «итого»

14. 0000 0111 = Получить деньги

15. 0000 1000 = Выдать сдачу покупателю

16. 0000 1001 = Открыть пустой пакет

17. 0101 0011 = Если в заказе нет бургера, перейти к шагу 19

18. 0000 1010 = Положить бургер в пакет

19. 0101 0110 = Если в заказе нет картошки, перейти к шагу 22

21. 0000 1011 = Положить картошку в пакет

22. 0101 1000 = Если в заказе нет колы, перейти к шагу 24

23. 0000 1100 = Положить колу в пакет

24. 0000 1101 = Выдать пакет покупателю

25. 0101 1011 = Если пришло время закрытия, перейти к шагу 27

26. 1000 0001 = Перейти к шагу 1

27. 0001 0000 = Идти домой

Примерно так и устроен код терминала в ресторане быстрого питания.

Первое "Великое изобретение"

Мы уже убедились, что соединяя обычными проводами степпер и некоторые регистры, можно получить только какую-то одну операцию. Но ведь можно соединить все эти регистры со степпером с помощью различных логических элементов! Теперь мы сможем выполнять любую операцию на выбор. Но как же мы будем выбирать?

И тут нашим первым великим изобретением будет способ выбора нужной операции. В ОЗУ будут храниться инструкции, которые скажут процессору, что нужно делать. И чтобы это заработало, нам понадобятся три вещи.

Первая вещь – это еще один регистр ЦП, в который будет записываться инструкция для ЦП. Этот регистр будет называться «Регистр инструкции» (IR - Instruction Register). Данные из шины будут поступать в IR, а из него - в Секцию управления ЦП, где биты будут выбирать одну из возможных операций. Вторая вещь – еще один регистр ЦП, который будет называться «Регистр адреса инструкции» (IAR - Instruction Address Register). Этот регистр имеет вход и выход. Подключен он к шине так же как и регистры общего назначения, только служит исключительно для того, чтобы хранить адрес RAM следующей инструкции, которую мы хотим поместить в IR. Третья вещь – это отдельная разводка соединений в секции управления. Эта вещь будет обеспечивать перемещение желаемой инструкции из RAM в IR, прибавлять 1 к адресу в IAR и выполнять действия, предусмотренные инструкцией из IR. По завершению очередной инструкции, степпер перезапускается, но теперь к IAR прибавлена единица, поэтому из ОЗУ будет получена не та же инструкция, а другая, расположенная в следующем адресе ОЗУ.

Результатом этих трех вещей и является «великое изобретение». Это именно то, что дает нам множество комбинаций взаимодействия АЛУ, шины, ОЗУ и регистров, что позволяет компьютеру выполнять различные действия. Все что нам нужно для работы этого механизма, это поместить инструкции в ОЗУ в виде последовательности байтов. Эта последовательность и называется «программой».

Итак, в нашем процессоре установлен степпер на семь шагов. Цель шага 7 – сбросить степпер и перейти к шагу 1. Таким образом, наш процессор способен выполнить 1 инструкцию за 6 тактов. Поэтому, если частота clk будет равна 1ГГц, процессор сможет выполнять 166 666 666 инструкций в секунду. Ниже изображен процессор уже с двумя новыми регистрами. У регистра IAR есть биты ‘e’ и ‘s’, а вот у регистра IR есть только ‘s’ (как и у TMP и MAR). Обусловлено это тем, выход IR не подключен к шине, поэтому ‘e’ здесь не нужен.

Ниже приведена схема подключений в секции управления. Эти подключения выполняют часть «выборки» командного цикла. Для этого задействованы первые три шага степпера.

На данной схеме показаны первые три шага степпера, которые приводят к извлечению следующей инструкции из ОЗУ. Остальные же три шага выполняют инструкцию. Именно то, что будет выполнено во время шагов 4, 5,6 – и есть содержание инструкции. Затем степпер запускается заново, получает следующую инструкцию и выполняет ее. Внизу схемы находится регистр инструкции. Биты IR пронумерованы и позже будут рассмотрены более подробно.

Теперь рассмотрим более подробно, что происходит в первые три шага. Шаг 1 самый сложный потому, что мы выполняем две задачи одновременно. Во-первых, мы выставляем ‘e’ IAR и ‘s’ MAR, тем самым во время «clk e» мы копируем данные из IAR в шину, а во время «clk s» устанавливаем данные из шины в MAR. А во-вторых, АЛУ, в свою очередь всегда производит вычисления двух чисел, находящихся в шине и в BUS1 и выводит результат к Аккумулятору. И так как на момент первого шага инструкция еще не пришла, на входе инструкции АЛУ сей час 000, что соответствует сложению (инструкция ADD). А еще на первом шаге активен управляющий бит BUS1, поэтому АЛУ получает из BUS1 число 0000 0001. АЛУ складывает IAR+1 и выводит результат в ACC, ‘s’ бит которого сейчас активен. Таким образом, в первом шаге в ACC записывается значение IAR+1 во время «clk s».

Шаг 2 включает выбранный байт в ОЗУ.

Обратите внимание: США делают ставку на квантовые компьютеры.

Данные из этого байта переходят в шину и устанавливаются в регистр IR.

Шаг 3. Теперь нам нужно обновить значение IAR. В шаге 1 мы увеличили его значение на 1, но это значение находится в Аккумуляторе. Именно для этого шаг 3 подключен к ‘e’ ACC и ‘s’ IAR.

Далее, во время шагов 4, 5 и 6 будет выполняться инструкция из IR. После выполнения инструкции, степпер сбросится и все начнется заново, но теперь IAR увеличился на 1, поэтому из RAM будет извлечена инструкция, которая находится в следующем по порядку адресе.

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

Инструкции

Теперь у нас есть новый регистр IR, который будет сообщать секции управления, что нужно делать. Значения этого регистра будут называться «Коды инструкций». Сколько же может быть разных инструкций? Наш регистр инструкций 8-ми битный, поэтому мы можем придумать до 256 различных инструкций. Здесь мы придумаем только девять инструкций. Эти инструкции будут перемещать байты из RAM в регистры и обратно, а иногда и через АЛУ. Далее мы отдельно рассмотрим каждую такую инструкцию и ее реализацию на схеме.

Арифметические и логические инструкции

Рассмотрим первый тип инструкций, который использует АЛУ, как операция ADD, рассмотренная ранее. У нашего АЛУ есть восемь возможных действий. Для выполнения некоторых из них используется два байта ввода, а для других – один байт ввода. Результатом же всегда является только один байт вывода. Этим типом инструкций будет выбираться одна из возможных операций АЛУ и два регистра. На самом деле это самый универсальный вид инструкций. Так как у нашего АЛУ 8 возможных действий, а выбрать из 4 регистров можно дважды, то всего вариаций может быть 8х4х4=128. Таким образом, это не просто инструкция, а целый класс инструкций, которые используют один и тот же способ соединений в контрольной секции. Вот код инструкции для инструкций АЛУ. Если первый бит в регистре равен 1, то это инструкция АЛУ.

Если первый бит равен 1, то следующие три бита определяют инструкцию АЛУ, следующие два бита выбирают первый регистр, оставшиеся два бита – второй регистр.

Таким образом, чтобы сложить два числа из регистра R1 и R2, нужно записать такую инструкцию: 1000 0110.

Если же вы выберите такую операцию, как SHL, SHR, NOT, тогда байт из Reg A поступит в АЛУ, с ним проведется операция, а результат запишется в Reg B. Так же можно записать дважды один и тот же регистр, например, 1110 0000. В данном случае будет произведена операция XOR между числом из R0 и числом из R0. В данном случае результатом будет число 0000 0000, которое далее и запишется в R0.

Операция CMP принимает два байта на входе, но не выдает байт на выход. Схема соединений для инструкций АЛУ довольно проста. Но есть одно дополнение, которым пользуются многие типы инструкций. Вспомним главу «Возвращение к чему-то полезному», где мы использовали два регистра. Мы соединяли регистры и степпер с помощью логических элементов И. Во многих инструкциях, как и в инструкциях АЛУ в том числе, используются два байта. И чтобы использовать в операциях не конкретные байты, например только R0 для Reg A и R1 для Reg B, а любые из доступных, нам необходимо сделать нечто подобное, применив элементы И. Ниже приведена схема с решением данной задачи:

Сначала рассмотрим правую часть схемы. Чтобы выбрать записать регистр Reg B, нам нужно подключить провод «Reg B» к соответствующему «шагу». Провод «clk s» одновременно подключен ко всем четырем элементам И. Теперь в момент работы конкретного шага, на каждом элементе И включены по два входа. Третий вход каждого элемента подключен к «дешифратору 2х4», а дешифратор, в свою очередь, может включить только один из выходов. Какой именно выход включить, ему сообщают 6 и 7 биты регистра IR.

Левая часть схемы похожа на правую, только здесь всего по два. Для таких инструкций АЛУ, как ADD, например, требуется два входящих байта. По одному на каждый вход АЛУ. Здесь провод «clk e» подключен ко всем элементам И. А вот провода «Reg A» и «Reg B» подключены к разным дешифраторам в соответствии с назначениями битов инструкции. На входы элементов И, которые подключены провода «Reg A» или «Reg B», сигнал приходит во время разных шагов. Поэтому на выходе никогда не будет выбрано два регистра одновременно. Элементы ИЛИ на выходах стоят лишь потому, нельзя вот так просто взять и соединить между собой выходы двух элементов с разным сигналом.

Что же происходит, если полученная инструкция начинается с 1? Это значит, что перед нами АЛУ инструкция и нам нужно сделать три вещи. Сначала, мы переместим Reg B в TMP. Затем, сообщить АЛУ, какую операцию нужно выполнить, установить на шину байт из Reg Aи установить выход АЛУ на ACC. И теперь переместить байт из ACC в Reg B.

На схеме ниже показаны соединения и логические вентили, которые обеспечивают инструкции АЛУ.

Бит 0 регистра IR определяет, является ли байт инструкцией АЛУ и при состоянии «1» включает возможность проведения соответствующих операций через логические элементы И. Обратите внимание на три вентиля 3И чуть выше и слева от регистра IR. Один вход всех вентилей подключен к 0 биту IR, второй вход всех вентилей подключен к шагу 5 степпера, а третий вход каждого вентиля подключен к 1, 2 и 3 битам IR. Таким образом, АЛУ получит инструкцию из 1, 2 и3 битов IR только в том случае, когда 0-й бит IR будет равен 1, а шаг 5 степпера будет активен. Во всех остальных случаях АЛУ будет получать инструкцию 000 (ADD).

Как АЛУ получает инструкцию, мы разобрались. Теперь проследуем дальше по проводу 0-го бита регистра IR. К нему подключены еще три вентиля И. Другие входы этих вентилей подключены к шагам 4, 5 и 6 степпера. Первый вентиль подключен к шагу 4, а выход его подключает регистр Reg B к шине и устанавливает TMP. На самом деле этот шаг нужен недля всех операций АЛУ. Такими операциями как SHL, SHR и NOT, данный шаг не используется, но он им не вредит.

Второй вентиль вторым входом подключен к шагу 5, а его выход подключает регистр Reg A к шине и устанавливает ACC. ALU на шаге 5 теперь получает два входных байта из TMP и из шины, а так же получает «op код» из 1, 2 и 3 битов регистра IR и устанавливает результат в ACC.

Третий вентиль вторым входом подключен к шагу 6, а выходом подключает ACC к шине и устанавливает данные в регистр Reg B. Третий же вход третьего вентиля И будет активирован при всех инструкциях, кроме CMP (op код 111), когда результат АЛУ нам не нужно сохранять в Reg B. Таким образом, при поступлении инструкции 111, Нижний вентиль 3И включит выход, инвертор инвертирует сигнал и на третий вход третьего вентиля поступит 0. Поэтому на 6 шаге ACC не подключится к шине, а ‘s’ Reg B не включится для записи.

На этом инструкция заканчивается, шаг 7 сбрасывает степпер на шаг 1, и все начинается заново и т.д. и т.д.

Теперь пришло время для очередного изобретения, а именно способа сокращенно и понятно записывать инструкции ЦП на бумагу. Ведь вам вряд ли захочется запоминать значения команд в двоичном виде. Да и сходу определить, что означает, например, инструкция 1000 1011, тоже тяжеловато. Значит она «Сложить R2 и R3», но так ли это очевидно с первого взгляда? Куда проще написать что-то вроде "СЛОЖИТЬ R2, R3" или "СРАВНИТЬ R2, R3". У такого написания инструкций есть название «Компьютерный язык». Но вообще такой низкоуровневый язык еще называется «Ассемблер». Теперь наши инструкции для АЛУ станут первыми восемью словами нашего нового языка.

Теперь написать программу для компьютера будет легко. Но прежде чем поместить код программы в ОЗУ для исполнения, его нужно будет сначала перевести с компьютерного языка в фактический код инструкции.

#компьютеры #наука и техника #образование #начинающим радиолюбителям #электроника начинающим #процессоры

Часть 7 - Назад Далее - Часть 9

Еще по теме здесь: Новости науки и техники.

Источник: Как устроен компьютер? Часть 8 (Как работают инструкции).