Регистры, память и инструкции: архитектура набора инструкций
Архитектура набора инструкций (ISA) является самым низкоуровневым абстрактным уровнем для компьютеров. ISA разрабатываются так, чтобы быть по возможности ближе к аппаратному обеспечению, при этом быть достаточно общими для применения на большинстве компьютеров. Именно поэтому ISA крайне неудобны для людей, и лишь немногие разработчики программирования используют их напрямую, а более высокоуровневые языки программирования абстрагируют компьютеры полностью от ISA. Однако понимание ISA является хорошим отправным пунктом для понимания аппаратного обеспечения компьютера и помогает объяснить множество выборов дизайна в языках программирования более высокого уровня и приложениях программного обеспечения, именно поэтому они здесь введены.
Существует несколько различных ISA, таких как x86, ARM, MIPS и RISC-V. Каждая из них разработана немного иначе (или совсем по-другому, когда речь идет о семействах архитектур CISC и RISC), но некоторые концепции являются общими для почти всех из них. Эти концепции являются фундаментальной абстракцией, которая применима к почти всем аппаратным средствам компьютера и рассматриваются в данном разделе.
Регистры, память и инструкции: самые общие абстракции компьютеров
Почти все ISA используют следующие концепции:
- Существует конечное множество регистров, в которых можно хранить данные.
- Существует (почти бесконечная) память, в которой можно хранить больше данных. Каждое место в памяти может содержать некоторые данные и имеет связанный с ним адрес; этот адрес используется для доступа к данным, хранящимся в этом месте.
- Есть "процессор", который поддерживает выполнение конечного набора инструкций, которые каким-то образом изменяют регистры или память. Инструкции хранятся в памяти и выполняются последовательно.
- Существует специальный регистр (обычно называемый "счетчик программы" или "PC"), который содержит адрес в памяти. В каждый момент времени "процессор" читает данные по этому адресу в памяти, интерпретирует эти данные как инструкцию, выполняет ее, затем каким-то образом обновляет PC.
Важные аспекты, которые следует отметить в приведенных выше концепциях:
- По сравнению с памятью, регистры могут содержать очень ограниченное количество данных. В большинстве ISA количество регистров меньше 100 и общее количество данных, которое может быть содержано во всех регистрах, вряд ли превысит 1 мегабайт (MB). В отличие от этого, память гораздо больше: современные компьютеры обычно имеют от 4 до сотен гигабайт (GB) памяти; даже мобильные телефоны обычно имеют 4 гигабайта памяти или более.
- То, что компьютер будет делать, начиная с определенного момента времени, полностью определяется данными, содержащимися в регистрах (включая PC) и памяти. Вы можете представлять себе регистры и память как "состояние" программы; это состояние полностью определяет поведение программы.
- Инструкции, поддерживаемые ISA, обычно являются очень простыми операциями (ISA семейство CISC, или "Комплексные наборы инструкций", поддерживает более сложные инструкции, но их функциональность все равно крайне ограничена по сравнению с полноценными программами), такими как "сложение данных в регистре 5 и регистре 11 и сохранение результата в регистре 0", "загрузка значения по адресу памяти 122 в регистр 1" или "перемещение PC на 40 позиций памяти вперед". Эти инструкции не являются полноценными компьютерными программами; они используются в качестве строительных блоков для создания более крупных программ. Сочетая эти простые инструкции (называемые "программированием"), можно создавать программы, выполняющие практически все.
Зачем нам нужны регистры?
Возможно, вы задаетесь вопросом, зачем нам вообще нужны регистры: поскольку регистры и память служат "состоянием" программы, почему бы нам не использовать исключительно память? В конце концов, регистры могут хранить лишь очень ограниченное количество данных, тогда как память гораздо больше.
Ответ связан с тем, как работают аппаратные средства компьютеров. Хотя регистры небольшие, они очень быстрые; наоборот, память большая, но также медленная (по сравнению с регистрами). В результате типичная практика состоит в том, чтобы хранить данные, к которым часто нужен доступ, в регистрах, а остальные данные хранить в памяти.
Это хороший пример того, как ISA близки к аппаратному обеспечению, и, как видите, хотя абстракции являются "общими и абстрактными характеристиками", они, как правило, зависят от и отражают основные объекты, к которым они применяются.
Другие ISA
Хотя это, что было представлено здесь, применимо к подавляющему большинству ISA, есть ISA, которые абстрагируют компьютеры иначе. Например, WebAssembly (WASM) - это архитектура, основанная на стеке, которая не имеет регистров.
Как выполняются компьютерные программы?
Представьте себе человека с карандашом, держащего блокнот. В начале блокнот находится на определенной странице, затем в каждый момент времени человек читает страницу, выполняет что-то (либо делает вычисления и запоминает результат, либо пишет что-то на другую страницу) в соответствии с тем, что говорит эта страница, переходит на другую страницу, и так повторяется.
Это хорошая аналогия того, как программа выполняется на компьютере: человек является процессором; блокнот - память, а память человеческого мозга - регистры.
Как уже упоминалось, ISA поддерживает только очень ограниченное количество инструкций с очень ограниченными возможностями; эти инструкции служат в качестве строительных блоков для более крупных приложений программного обеспечения. Практически каждое программное приложение сводится к большому числу (от сотен тысяч до миллионов) ISA инструкций, когда оно выполняется на аппаратном обеспечении. В основном способ, которым программы запускаются, определяется ISA, и выглядит следующим образом:
- В начале память и регистры инициализируются некоторыми значениями. Обычно в памяти есть специальный сегмент, содержащий все инструкции; инструкции, хранящиеся в этом сегменте, являются "программой".
- В каждый момент времени процессор считывает инструкцию, определенную ISA, по адресу памяти, указанному PC, выполняет ее (либо делает какие-то вычисления и записывает результат в регистр, либо записывает какие-то данные по определенному адресу в памяти и т. д.), и обновляет PC (обычно на адрес следующей инструкции, но также может быть в другом месте).
- Этот процесс повторяется до тех пор, пока программа не завершится.
graph TD
A([начало]) --> B([считать инструкцию])
B --> C([выполнить инструкцию])
C --> D([обновить PC])
D --> B
Что, если есть несколько программ?
Возможно, вы задаетесь вопросом, что станет, если на одном компьютере запускается несколько программ? Поскольку они используют одну и ту же область памяти, они не будут мешать друг другу? И как они выполняются? Выполняются ли они одна за другой или одновременно?
Короткий ответ таков, что операционная система предоставляет еще один уровень абстракции, который устраняет все эти проблемы. Простыми словами, операционная система "виртуализирует" аппаратное обеспечение компьютера и создает иллюзию множества независимых компьютеров, работающих одновременно. Каждой программе выделяется свой такой "виртуальный" компьютер; с точки зрения программы на этом компьютере никого больше нет, поэтому никаких взаимодействий вообще не происходит.
Но то, как операционная система создает эту иллюзию, выходит за рамки этого раздела.
Заключение
В этом разделе мы рассмотрели самые низкоуровневые абстракции компьютеров: архитектуру набора инструкций (ISA). По сравнению с другими абстракциями компьютеров, такими как языки программирования более высокого уровня, ISA ближе к аппаратному обеспечению, но также менее удобны для пользователя. Хотя разработчики обычно используют совершенно другие абстракции при программировании, понимание ISA является хорошей основой для понимания работы компьютеров.
Почти все ISA имеют набор регистров, память и определяют набор поддерживаемых простых инструкций. Один особый регистр называется "счетчик программы (PC)". Способ работы программы сводится к следующему: "загрузка инструкции по адресу PC - выполнение инструкции - обновление PC - повторение". Инструкции ISA служат как строительные блоки для более сложных приложений программного обеспечения; практически каждое программное приложение сводится к большому числу простых инструкций ISA, когда оно выполняется на аппаратном обеспечении.
Поздравляю, теперь вы понимаете, как работает аппаратное обеспечение компьютера! Реальные компьютерные аппаратные средства намного сложнее, чем ISA, но пока ISA являются хорошим приближением к реальному аппаратному обеспечению.
Затем мы познакомимся с более высокоуровневыми абстракциями, которые основаны на ISA и обнаруживаются в большинстве низкоуровневых языков программирования, таких как C/C++ и Rust.
Примеры запросов к ИИ
Если вы хотите узнать больше о темах, рассмотренных в этом разделе, вы можете обратиться к ИИ, такому как ChatGPT.
Вот несколько примеров запросов, чтобы начать:
- Можете ли вы кратко описать архитектуру ARM и его инструкции?
- Можете ли вы привести пример кода ассемблера ARM и объяснить, что он делает?
- В чем разница между CISC и RISC?
- Как архитектуры набора инструкций сравниваются с машиной Тьюринга? Почему нет регистров в машине Тьюринга? Почему в ISA есть регистры?
- Какие наиболее популярные архитектуры набора инструкций в наши дни?