Несколько месяцев назад меня осенило, что я не совсем понимаю, как компьютеры работают под капотом. Я до сих пор не понимаю, как работают современные компьютеры.

Однако, пройдя путь через Но откуда это знать? Дж. Кларка Скотта, книга, в которой описаны элементы простого 8-битного компьютера от вентилей NAND до регистров , RAM, биты CPU, ALU и I / O, мне очень захотелось реализовать это в коде.

Хотя меня не так интересует физика схемотехники, в книге почти не просматривается поверхность этих вод и дается аккуратный обзор проводки и того, как биты перемещаются по системе без необходимого электрического инженерные знания. Для меня, хотя я не могу привыкнуть к описаниям книг, я должен видеть вещи в действии и извлекать уроки из своих неизбежных ошибок, которые заставили меня наметить курс в бурном море написания схемы в коде и немного заплакать. Это.

Плоды моего путешествия можно увидеть на простом компьютере; простой компьютер, который все вычисляет.

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

Он обрабатывает ввод с клавиатуры и отображает текст на дисплее, используя кропотливо созданный набор глифов для профессионального шрифта, который я назвал Daniel Code Pro. Единственный чит-бит заключается в том, чтобы заставить работать ввод с клавиатуры и вывод на дисплей. Мне пришлось подключить каналы go, чтобы общаться с внешним миром через GLFW, но остальное - смоделированная схема.

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

Но зачем ты это делаешь?

«Я видел, как тринадцатилетние дети делали это в Minecraft, вспомните, когда вы построили НАСТОЯЩИЙ процессор из телеграфных реле»

Моя ментальная модель вычислений застряла в учебниках по информатике для начинающих, а процессор, на котором работает эмулятор gameboy, который я написал еще в 2013 году, на самом деле не похож на процессоры, которые работают сегодня. Даже говоря это, эмулятор - это просто конечный автомат, он не описывает вещи на уровне логических элементов. Вы можете реализовать большую часть этого, используя только оператор switch и сохраняя состояние регистров.

Итак, я пытаюсь лучше понять этот материал, потому что я не знаю, что такое кеши L1 / L2, я не знаю, что такое конвейерная обработка, я не совсем уверен, что понимаю документы об уязвимостях Meltdown и Spectre. Кто-то сказал мне, что они оптимизируют свой код для использования кешей ЦП, я не знаю, как это проверить, кроме как поверить им на слово. Я не совсем понимаю, что означают все инструкции x86. Я не понимаю, как люди работают без нагрузки на GPU или TPU. Не знаю, что такое ТПУ. Я не знаю, как использовать инструкции SIMD.

Но все это основано на знаниях, которые вам нужны, чтобы заработать свои полоски, так что я не доберусь до этого, не прочитав сначала карту. А это значит вернуться к основам и запачкать руки чем-нибудь простым. «Компьютер Скотта», описанный в книге, прост. Вот в чем причина.

Великий Скотт! Оно живое!

Компьютер Скотта представляет собой 8-битный процессор, подключенный к 256 байтам оперативной памяти, все они подключены через 8-битную системную шину. Он имеет 4 регистра общего назначения и может выполнять 17 машинных инструкций. Кто-то построил визуальный симулятор для Интернета здесь, что действительно круто, я боюсь представить, сколько времени потребовалось, чтобы отслеживать все состояния проводки!

Книга отправляет вас в путешествие от скромных ворот NAND к Биту памяти, к регистру, а затем продолжает наслоить компоненты, пока вы не получите что-то похожее на приведенное выше. Я действительно рекомендую прочитать его, даже если вы уже знакомы с концепциями, потому что это довольно хороший обзор. Я не рекомендую версию Kindle, потому что диаграммы иногда трудно увеличить и расшифровать на экране. По моему опыту, постоянная проблема для Kindle.

Единственное, что отличает мой компьютер от других, это то, что я обновил его до 16-битного, чтобы иметь больше памяти, с которой можно поиграть, поскольку хранение даже только глифов для таблицы ASCII затмило бы большую часть 8-битной машины, описанной в книге. , осталось не так много места для полезного кода.

Мой путь развития

Во время разработки на самом деле это был просто случай чтения текста, просмотра диаграмм, а затем попытки перевести это с использованием кода языка программирования общего назначения и определенно не с использованием чего-то, что предназначено для разработки интегральных схем. Причина, по которой я написал это на Go, в том, что я немного знаю Go. Скептики могут вмешаться и сказать: ты мерзкий идиот! Не могу поверить, что вы не потратили все свое время на изучение VHDL, Verilog или LogSim или чего-то еще, но к тому моменту я уже написал свои биты, байты и NAND, я был слишком глубоко. Может быть, я выучу их в следующий раз и буду плакать о потраченном зря времени, но это мой крест.

По большому счету, большая часть компьютера просто передает кучу логических значений, поэтому любой дружественный к логическим значениям язык выполнит эту работу.

Применение схемы к этим логическим значениям - это то, что помогает вам (программисту) понять ее значение, и самое важное решение, которое нужно принять каждому, - это решить, какой порядок байтов будет использовать ваша система, и убедиться, что все компоненты передают вещи в и из автобус в правильном порядке.

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

Разработка действительно заняла некоторое время, может быть, около месяца или двух в мое свободное время, но как только ЦП был готов и успешно смог выполнить 2 + 2 = 5, я был счастлив.

Что ж, до тех пор, пока в книге не обсуждались функции ввода-вывода, с дизайном простой клавиатуры и интерфейса дисплея, чтобы вы могли доставить вещи в машину и из нее. Я уже дошел до этого, нет смысла оставлять его в полуготовом состоянии. Я поставил себе цель иметь возможность набирать что-нибудь на клавиатуре и отображать буквы на дисплее.

Периферийные устройства

Периферийные устройства используют шаблон адаптера, чтобы действовать как аппаратный интерфейс между ЦП и внешним миром. Наверное, не так уж сложно предположить, что это было источником вдохновения для шаблона проектирования программного обеспечения.

При таком разделении задач было довольно просто подключить другой конец клавиатуры и отображать к окну, управляемому GLFW. Фактически, я просто вытащил большую часть кода из своего эмулятора и немного изменил его форму, используя каналы go, чтобы действовать как входящие и исходящие сигналы в машину.

Воплощая это в жизнь

Вероятно, это была самая сложная часть или, по крайней мере, самая громоздкая. Писать сборку с таким ограниченным набором команд - отстой. Написание ассемблера с использованием грубого ассемблера - отстой еще больше, потому что вы не можете грозить кулаком кому-либо, кроме себя.

Самая большая проблема заключалась в том, чтобы манипулировать 4 регистрами и отслеживать их, извлекать и помещать данные в память в качестве временного хранилища. Делая это, я вспомнил, что у процессора Gameboy был регистр указателя стека, чтобы вы могли нажимать и показывать состояние. К сожалению, у этого компьютера нет такой роскоши, поэтому я в основном перемещал вещи в память и из памяти на индивидуальной основе.

Единственная псевдо-инструкция, на реализацию которой я потратил время, - это CALL для помощи при вызове функций, это позволяет вам запустить функцию, а затем вернуться к точке после того, как функция была вызвана. Однако без этого стека вы можете вызывать только один уровень.

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

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

Однако это было непросто, самая сложная часть программы для написания текста заключалась в том, чтобы правильно вычислить, когда нужно переходить на новую строку или что происходит, когда вы нажимаете клавишу ввода.

main-getInput:
	CALL ROUTINE-io-pollKeyboard
	CALL ROUTINE-io-drawFontCharacter
	JMP main-getInput

(Основной цикл программы записи текста)

Я не дошел до реализации клавиши Backspace или каких-либо клавиш-модификаторов. Заставил меня понять, сколько работы нужно затратить на создание текстовых редакторов и насколько это, вероятно, утомительно.

При размышлении

Для меня это был веселый и очень полезный проект. В процессе программирования на языке ассемблера я почти забыл о срабатывании логических элементов И-НЕ, И и ИЛИ. Я поднялся на уровни абстракции выше.

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

  • Как биты перемещаются между всеми компонентами с помощью шины
  • Как работает простой ALU
  • Как выглядит простой цикл Fetch-Decode-Execute
  • Что машина без регистра указателя стека + концепция стека - отстой
  • Что машина без прерываний - отстой
  • Что такое ассемблер и что он делает
  • Как периферия взаимодействует с простым процессором
  • Как работают простые шрифты и подход к их отображению на дисплее
  • Как может выглядеть простая операционная система

Так что же дальше? В книге сказано, что никто не создавал такой компьютер с 1952 года, а это значит, что у меня есть 67 лет материала, который нужно освежить, так что это должно занять меня на некоторое время. Я вижу, что руководство по x86 занимает 4800 страниц, этого достаточно для легкого чтения перед сном.

Может быть, у меня будет небольшое увлечение операционной системой, флирт с языком C, прискорбный вечер попытки припаять комплект PiDP-11, а затем, вероятно, прекратить это. Я не знаю, посмотрим.

Со всей серьезностью, хотя я думаю, что в следующий раз я начну изучать материал, основанный на RISC, возможно, RISC-V, но, вероятно, начну с ранних процессоров RISC, чтобы понять происхождение. Современные процессоры имеют гораздо больше функций, таких как кеширование и прочее, поэтому я тоже хочу понять их. Там есть чему поучиться.

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

Первоначально опубликовано на https://djhworld.github.io 21 мая 2019 г.