Как можно заметить, в сложной адресации (типа косвенно-индексной со смещением и масштабированием) не могут участвовать произвольные регистры. Соответствие между командами и кодом, выполняемый процессором, происходит с помощью кода операции в команде. В коде операции указывается, с какими регистрами работает процессор, и как и с помощью каких других регистров осуществляется адресация операндов. Подробнее об этом смотри руководство по конкретному процессору.
Следует отметить, что в RISC-процессорах нет возможности адресации операнда из оперативной памяти, а возможна только загрузка данных в регистр. Соответственно упрощается устройство управления, и все команды могут иметь одинаковую длину.
§14.5. Особенности "стековой адресации".
Во всех CISC-процессорах аппаратно поддерживается стек, т.е. область оперативной памяти, предназначенная для временного хранения любой информации. Для стека характерны две операции: включение в стек "вталкивание" и извлечение "выталкивание" данных из стека. Включения и извлечение производятся с одного конца, называемого вершиной стека (Top Of Stack -- TOS или Stack Top -- ST), таким образом, что последнее включение в стек извлекается из него первым. Такая дисциплина называется LIFO (Last In -- First Out, "последним пришел -- первым ушел").
Предполагается, что область памяти для стека находится в специальном сегменте стека. В микропроцессорах Intel его адрес находится в паре SS:SP и SS:ESP, причем регистр SS содержит базу регистра, а вершина стека адресуется смещением в SP или ESP. Алгоритм работы со стеком в микропроцессоре i80386 и старше в P-режиме следующий:
1. Начало алгоритма вставки в стек.
2. Проверяется значение в ESP.
3. Если оно меньше четырех, то генерируется особый случай нарушения стека.
4. Происходит декремент ESP на четыре и операнд сохраняется по адресу SS:[ESP].
5. Конец алгоритма вставки в стек.
1. Начало алгоритма извлечения из стека.
2. Проверяется значение в ESP.
3. Если адрес SS:[ESP] находится вне пределах сегмента стека (адрес слишком большой и не помещается в стек), формируется особый случай нарушения стека.
4. Если же обращение разрешенное, то считываются данные по адресу SS:[ESP] и осуществляется инкремент ESP на четыре.
5. Конец алгоритма извлечения из памяти.
В стек можно включить содержимое регистра, ячейки памяти или константу (процессор i8086/88 включать в стек константы не может). Извлечь данные из стека можно в регистр или ячейку памяти.
Как видно из предложенного алгоритма, сегмент стека заполняется не "с ног до головы" (т.е. от меньших адресов к большему), а наоборот, от больших адресов к меньшим. Это свойство сегмента специально указывается особым флажком в дескрипторе сегмента.
Сказанное относится к реализации стека в микропроцессорах корпорации Intel. В микропроцессорах Motorola вершина стека автоматически привязана к регистру A7 (и его копии A7' в режиме супервизора). Далее распределением базового адреса сегмента стека и управление его работой перекладывается на плечи операционной системы (т.е. на системного программиста). Отметим, что загрузка стека для программы супервизора осуществляется только при первоначальной загрузки процессора и программно недоступна, а загрузка стека программы пользователя является привилегированной командой и выполняется только в режиме супервизора. Об этом надо помнить, манипулируя со стеком на этой платформе.
Системные регистры центрального процессора.
Системные регистры (System registers) предназначены для временного хранения операндов (смотри п. D.1.) и результатов вычислений. но не смотря на свое "единое" предназначение, эти устройства различаются по своим функциям. По ним регистры можно разделить на регистры данных, аккумуляторы, адресные и сегментные регистры, регистры стеков, указателями и счетчики команд, регистры флагов (или, как их раньше называли, слово состояния программы, Program Status Word) и прочие. Рассмотрим их по-подробнее.
Регистры данных
Регистры данных (Data Register) применяется для хранения промежуточных данных, участвуют в арифметических и логических операциях процессора. Аккумулятор, базовые и индексные регистры также можно использовать в качестве регистров данных.
В некоторых процессорах (например, в процессорах больших ЭВМ IBM 360/370, CISC-процессорах Motorola) все регистры данных равноправны и могут одинаково участвовать во всех операциях процессора. В процессорах Motorola даже стирается различие между адресными регистрами и регистрами данных! Однако с усложнением микропроцессоров специализация их системных регистров усилилась. Поэтому в современных микропроцессорах выделяются следующие типы регистров данных.
Аккумулятор (Accumulator) -- это регистр, который применяется для хранения промежуточных результатов вычисления. Именно его предпочтительно выбирать в качестве хранения результата действия арифметической и логической операции. Он содержит первый множитель или делимое в операциях умножения/деления. при этом многие операции с участием этого регистра (не обязательно умножение и деление) часто выполняется быстрее [В.Л. Григорьев. Микропроцессор i486. Архитектура и программирование.//М.: "МИКАП", 1993 г. -- стр. 14]. Он называется "аккумулятором" потому, что он как бы "накапливает" (аккумулирует) результаты вычислений перед их посылкой в память компьютера.
Счетчик повторений (Counter). Этот регистр участвует в качестве счетчика для некоторых команд (сдвига, манипулирования со строками, цепочками, организации циклов и повторений.) Подробнее смотри [А.В. Нестеренко. ЭВМ и профессия программиста./М.: Просвещение, 1990.]
Регистр "вершины стека" присутствует в CISC-процессорах Motorola. Содержимое этого регистра синхронизируется с вершиной стека микропроцессора, расположенного в оперативной памяти. Вообще использование стека в CISC-процессорах компенсирует небольшое количество регистров в них, и является общепринятым. Таким образом существуют отдельные операции извлечения из стека и записи в стек. Подробнее об операциях со стеком смотри раздел D.4.2.
Индексные регистры (Index register) участвуют в операциях с индексной адресацией. Под этими операциями понимают те, в которых адрес элемента в памяти вычисляется, например, по правилу: <база>+<содержимое индексного регистра>*<длина элемента данных>. Эта адресация используется при операциях с массивами, строками и другими линейно-упорядоченными объектами (то есть объектами однотипных данных, расположенных в памяти "подряд"). При некоторых операциях различают индекс источника (Source Index) и индекс получателя, или приемника (Destination Index). примером могут служить циклические операции со строками.
Адресные регистры
Адресные регистры (Address register) применяются для хранения адреса (или его части) ячейки в оперативной памяти. Этот адрес может участвовать в арифметических и логических операциях процессора. Во многих современных процессорах разделение регистров на адресные и регистры данных весьма условно: и в тех, и в других могут находиться как адрес, так и данные, а АЛУ не делает различий между адресом и данными. Однако в практике программирования до сих пор за определенными регистрами закрепилась функция хранения части адреса ячейки памяти. Более того, в микропроцессорах Motorola серии MC680x0 только адресные регистры могут использоваться в операциях адресации памяти, а за регистром A7 закреплена функция вершины стека.
Существуют следующие адресные регистры:
Базовый регистр (Base) -- служит для указания начального адреса объекта в памяти при операциях с массивами и неявной адресации. Подробнее о массивах смотри [А.В. Нестеренко. ЭВМ и профессия программиста. -- М.: Просвещение, 1990 - стр. 64] и приложение A данной книги, а о неявной адресации -- смотри раздел D.3, посвященный адресации памяти.
Указатель стека (Stack Pointer) -- неявно используется в некоторых процессорах (в частности, Intel и Motorola) для организации работы со стеком. В качестве таких операций может служить, например, операции записи в стек и извлечения из стека, вызов подпрограммы и возврат в нее, вызов программ обработки прерываний, возврат из прерывания, переключения на другую задачу, изменение текущего уровня привилегий и некоторые другие. В микропроцессорах семейства x86 в качестве указателя стека используется регистр SP (ESP в 32-х разрядных версиях), который адресует вершину стека в текущем сегменте стека. В микропроцессорах Motorola серии MC680x0 в качестве регистра-указателя стека используется адресный регистр A7, который как бы делится на указатель стека супервизора SSP (содержимое которого изменить невозможно) и указателя стека пользователя USP, изменять содержимое которого можно только в режиме супервизора. Подробнее о стеке смотри [В.Л. Григорьев. Микропроцессор i486. Книга 1. Архитектура и программирование. -- М.: ГРАНАЛ. 1993 - с. 446; ил. -- стр. 61-63]
Указатель базы (Base Pointer) -- используется для удобства доступа к данным в стеке, которые не находятся в его вершине (например, параметры подпрограмм, переменные с модификатором auto в программах на Си и т.д.)
К адресным регистрам можно отнести регистры сегментного и страничного разделения памяти, а также селекторы сегментов. Но о них будет сказано ниже в отдельном разделе.