Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | ||
|
Последний режим - это защищенный режим, в котором Pentium II работает
как Pentium II, а не как 8088. В этом режиме доступны 4 уровня привилегий, которые управляются битами во флаговом регистре. Уровень 0 соответствует привилегированному режиму на других компьютерах и имеет полный доступ к машине. Этот уровень используется операционной системой. Уровень 3 предназначен для пользовательских программ. Он блокирует доступ к определенным командам и регистрам управления, чтобы ошибки какой-нибудь пользовательской программы не привели к поломке всей машины. Уровни 1 и 2 используются редко. Pentium II имеет огромное адресное пространство. Память разделена на 16 384 сегмента, каждый из которых идет от адреса 0 до адреса 23J-1. Однако большинство операционных систем (включая UNIX и все версии WINDOWS) поддерживают только один
сегмент, поэтому большинство прикладных программ видят линейное адресное пространство в 232 байтов, а иногда часть этого пространства занимает сама операционная система. Каждый байт в адресном пространстве имеет свой адрес. Слова состоят из 32 битов. Байты нумеруются справа налево (то есть самый первый адрес соответствует самому младшему байту).
Регистры процессора Pentium II показаны на рис. 5.3. Первые четыре регистра ЕАХ, ЕВХ, ЕСХ и EDX 32-битные. Это регистры общего назначения, хотя у каждого из них есть определенные особенности. ЕАХ - основной арифметический регистр; ЕВХ предназначен для хранения указателей (адресов памяти); ЕСХ связан с организацией циклов; EDX нужен для умножения и деления - этот регистр вместе с ЕАХ содержит 64-битные произведения и делимые. Каждый из этих регистров имеет 16-разрядный регистр в младших 16 битах и 8-разрядный регистр в младших 8 битах. Данные регистры позволяют легко манипулировать 16-битными и 8-битными значениями соответственно. В компьютерах 8088 и 80286 есть только 8-битные и 16-битные регистры. 32-битные регистры появились в системе
80386 вместе с приставкой Е (Extended - расширенный).
Следующие три регистра также являются регистрами общего назначения, но
с большей степенью специализации. Регистры ESI и EDI предназначены для хранения указателей, особенно для команд манипулирования цепочками, где ESI указывает на входную цепочку, a EDI - на выходную цепочку. Регистр ЕВР тоже предназначен для хранения указателей. Обычно он используется для указания на основу текущего фрейма локальных переменных, как и регистр LV в машине IJVM. Такой регистр обычно называют указателем фрейма. Наконец, регистр ESP - это указатель стека.
Следующая группа регистров от CS до GS - сегментные регистры. Это электронные трилобиты - атавизмы, оставшиеся от процессора 8088, который обращался к 22Обайтам памяти, используя 16-битные адреса. Достаточно сказать, что когда Pentium II установлен на использование единого линейного 32-битного адресного пространства, их можно смело проигнорировать. Регистр EIP - это счетчик программ (Extended Instruction Pointer - расширенный указатель команд). Регистр EFLAGS - это флаговый регистр.
Общий обзор уровня команд системы UltraSPARC II
Архитектура SPARC была впервые введена в 1987 году компанией Sun Microsystems. Эта архитектура была одной из первых архитектур промышленного назначения типа RISC. Она была основана на исследовании, проведенном в Беркли в 80-е годы [110,113]. Изначально система SPARC была 32-разрядной архитектурой, но Ultra- SPARC II - это 64-разрядная машина, основанная на Version 9, и именно ее мы будем описывать в этой главе. В целях согласованности с остальными частями книги мы будем называть данную систему UltraSPARC II, хотя на уровне команд все машины UltraSPARC идентичны. Структура памяти машины UltraSPARC II очень проста: память представляет собой линейный массив из 2м байтов. К сожалению, память настолько велика (18 446 744 073 709 551 616 байтов), что в настоящее время ее невозможно реализовать. Современные реализации имеют ограничение на размер адресного пространства, к которому они могут обращаться (2й байтов у UltraSPARC II), но в будущем это число увеличится. Байты нумеруются слева направо, но нумерацию можно изменить и сделать ее справа налево, установив бит во флаговом регистре. Важно, что архитектура команд имеет больше байтов, чем требуется для реализации, поскольку в будущем, скорее в-его, понадобится увеличить размер памяти,
к которой может обращаться процессор. Одна из самых серьезных проблем при разработке архитектур состоит в том, что архитектура команд ограничивает размер адресуемой памяти. В информатике существует один вопрос, который совершенно невозможно разрешить: никогда не хватает того количества битов, которое имеется в данный момент. Когда-нибудь ваши внуки спросят у вас, как же могли работать компьютеры, которые содержат всего-навсего 32-битные адреса и только 4 Гбайт памяти.
Архитектура команд SPARC достаточно проста, хотя организация регистров
была немного усложнена, чтобы сделать вызовы процедур более эффективными. Практика показывает, что организация регистров требует больших усилий и в общем эти усилия не стоят того, но правило совместимости не позволяет избавиться от этого. В системе UltraSPARC II имеется две группы регистров: 32 64-битных регистра общего назначения и 32 регистра с плавающей точкой. Регистры общего назначения называются R0-R31, но в определенных контекстах используются другие названия. Варианты названий регистров и их функции приведены в табл. 5.1.
Все регистры общего назначения 64-битные. Все они, кроме R0, значение которого всегда равно 0, могут считываться и записываться при помощи различных команд загрузки и сохранения. Функции, приведенные в табл. 5.1, отчасти определены по соглашению, но отчасти основаны на том, как аппаратное обеспечение обрабатывает их. Вообще не стоит отклоняться от этих функций, если вы не являетесь крупным специалистом, блестяще разбирающимся в компьютерах SPARC. Программист должен быть уверен, что программа правильно обращается к регистрам и выполняет над ними допустимые арифметические действия. Например, очень легко загрузить числа с плавающей точкой в регистры общего назначения, а затем произвести над ними целочисленное сложение, операцию, которая приведет к полнейшей чепухе, но которую центральный процессор обязательно выполнит, если этого потребует программа.
Глобальные переменные используются для хранения констант, переменных и
указателей, которые нужны во всех процедурах, хотя они могут загружаться и перезагружаться при входе в процедуру и при выходе из процедуры, если нужно. Регистры 1х и Ох используются для передачи параметров процедурам, чтобы избежать обращений к памяти. Ниже мы расскажем, как это происходит. Специальные регистры используются для особых целей. Регистры FP и SP ограничивают текущий фрейм. Первый указывает на основу текущего фрейма и используется для обращения к локальным переменным, точно так же как LV на рис. 4.9. Второй указывает на текущую вершину стека и изменяется, когда слова помещаются в стек или выталкиваются оттуда. Значение регистра FP изменяется только при вызове и завершении процедуры. Третий специальный регистр - R31.
Он содержит адрес возврата для текущей процедуры. В действительности процессор UltraSPARC II имеет более 32 регистров общего назначения, но только 32 из них видны для программы в любой момент времени. Эта особенность, называемая регистровыми окнами, предназначена для повышения эффективности вызова процедур. Система регистровых окон проиллюстрирована рис. 5.4. Основная идея - имитировать стек, используя при этом регистры. То есть существует несколько наборов регистров, точно так же как и несколько Общий обзор уровня архитектуры команд 347
фреймов в стеке. Ровно 32 регистра общего назначения видны в любой момент. Регистр CWP (Current Window Pointer - указатель текущего окна) следит за тем, какой набор регистров используется в данный момент.
Команда вызова процедуры скрывает старый набор регистров и путем изменения CWP предоставляет новый набор, который может использовать вызванная процедура. Однако некоторые регистры переносятся из вызывающей процедуры к вызванной процедуре, что обеспечивает эффективный способ передачи параметров между процедурами. Для этого некоторые регистры переименовываются: после вызова процедуры прежние выходные регистры с R8 по R15 все еще видны, но теперь это входные регистры с R24 по R31. Восемь глобальных регистров не меняются. Это всегда один и тот же набор регистров. В отличие от памяти, которая квазибесконечна (по крайней мере, в отношении стеков), если происходит многократное вложение процедур, машина выходит из регистровых окон. В этот момент самый старый набор регистров сбрасывается в память, чтобы освободить новый набор. Точно так же после многократных выходов из процедур может понадобиться вызвать набор регистров из памяти. В целом
такая усложненность является большой помехой и, вообще говоря, не очень полезна. Такая система выгодна только в том случае, если нет многократных вложений процедур.
В системе UltraSPARC II есть также 32 регистра с плавающей точкой, которые могут содержать либо 32-битные (одинарная точность), либо 64-битные (двойная точность) значения. Возможно, также использовать пары этих регистров, чтобы поддерживать 128-битные значения.
Архитектура UltraSPARC II - архитектура загрузки/хранения. Это значит,
что единственные операции, которые непосредственно обращаются к памяти – это команды LOAD (загрузка) и STORE (сохранение), служащие для перемещения данных между регистрами и памятью. Все операнды для команд арифметических и логических действий должны браться из регистров или предоставляться самой командой (но не должны браться из памяти), и все результаты должны сохраняться в регистрах (но не в памяти).
Лекция 13. Адресация.
1. Способы адресация.
2. Ортогональность кодов операций и способов адресации.
3. Способы адресации Pentium II.
1.Способы адресации
До сих пор мы не рассказывали о том, как интерпретируются биты адресного поля для нахождения операнда. Один из возможных вариантов состоит в том, что они содержат адрес операнда. Помимо огромного поля, необходимого для определения полного адреса памяти, данный метод имеет еще одно ограничение: этот адрес должен определяться во время компиляции. Существуют и другие возможности, которые обеспечивают более короткие спецификации, а также могут определять адреса динамически. В следующих разделах мы рассмотрим некоторые из этих форм, которые называются способами адресации.
Непосредственная адресация
Самый простой способ определения операнда - содержать в адресной части сам операнд, а не адрес операнда или какую-либо другую информацию, описывающую, где находится операнд. Такой операнд называется непосредственным операндом, поскольку он автоматически вызывается из памяти одновременно с командой; следовательно, он сразу непосредственно становится доступным. Один из вариантов команды с непосредственным адресом для загрузки в регистр R1 константы 4 показан на рис. 5.12.
При непосредственной адресации не требуется дополнительного обращения
к памяти для вызова операнда. Однако у такого способа адресации есть и некоторые недостатки.
Во-первых, таким способом можно работать только с константами.
Во-вторых, число значений ограничено размером поля. Тем не менее эта технология используется во многих архитектурах для определения целочисленных констант.
Прямая адресация
Следующий способ определения операнда - просто дать его полный адрес. Такой способ называется прямой адресацией. Как и непосредственная адресация, прямая адресация имеет некоторые ограничения: команда всегда будет иметь доступ только к одному и тому же адресу памяти. То есть значение может меняться, а адрес - нет. Таким образом, прямая адресация может использоваться только для доступа к глобальным переменным, адреса которых известны во время компиляции. Многие программы содержат глобальные переменные, поэтому этот способ широко используется. Каким образом компьютер узнает, какие адреса непосредственные, а какие прямые, мы обсудим позже.
Регистровая адресация
Регистровая адресация по сути сходна с прямой адресацией, только в данном случае вместо ячейки памяти определяется регистр. Поскольку регистры очень важны (из-за быстрого доступа и коротких адресов), этот способ адресации является самым распространенным на большинстве компьютеров. Многие компиляторы доходят до огромных размеров, чтобы определить, к каким переменным доступ будет осуществляться чаще всего (например, индекс цикла), и помещают эти переменные в регистры.
Такой способ адресации называют регистровой адресацией. В архитектурах
с загрузкой с запоминанием, например UltraSPARC II, практически все команды используют исключительно этот способ адресации. Он не используется только в том случае, когда операнд перемещается из памяти в регистр (команда LOAD) или из регистра в память (команда STORE). Даже в этих командах один из операндов является регистром - туда отправляется слово из памяти или оттуда перемещается слово в память.
Косвенная регистровая адресация
При таком способе адресации определяемый операнд берется из памяти или отправляется в память, но адрес не зафиксирован жестко в команде, как при прямой адресации. Вместо этого адрес содержится в регистре. Если адрес используется таким образом, он называется указателем. Преимущество косвенной адресации состоит в том, что можно обращаться к памяти, не имея в команде полного адреса. Кроме того, при разных выполнениях данной команды можно использовать разные слова памяти.
Чтобы понять, почему может быть полезно использование разных слов при каждом выполнении команды, представим себе цикл, который проходит по 1024-элементному одномерному массиву целых чисел для вычисления суммы элементов в регистре R1. Вне этого цикла какой-то другой регистр, например R2, может указывать первый элемент массива, а еще один регистр, например R3, может указывать первый адрес после массива. Массив содержит 1024 целых числа по 4 байта каждое. Если массив начинается с А, то первый адрес после массива будет А+4096. Типичная программа ассемблера, выполняющая это вычисление для двухадресной машины, показана в листинге 5.1.
В этой маленькой программе мы использовали несколько способов адреса-
ции. Первые три команды используют регистровую адресацию для первого операнда (пункт назначения) и непосредственную адресацию для второго операнда (константа, обозначенная символом #). Вторая команда помещает в R2 не содержимое А, а адрес А. Именно это и сообщает ассемблеру знак #. Сходным образом третья команда помещает в R3 первое слово после массива. Интересно отметить, что само тело цикла не содержит каких-либо адресов памяти. В четвертой команде используется регистровая и косвенная адресация. В пятой команде применяется регистровая и непосредственная адресация, а в шестой - два раза регистровая. Команда BLT могла бы использовать адрес памяти, однако более привлекательным является определение адреса с помощью 8-битного смещения, связанного с самой командой BLT. Таким образом, полностью избегая адресов памяти, мы получили короткий и быстрый цикл. Кстати, эта программа предназначена для Pentium II, только мы переименовали команды и регистры и для упрощения понимания изменили запись. Теоретически есть еще один способ выполнения этого вычисления без использования косвенной регистровой адресации. Этот цикл мог бы содержать команду для прибавления А к регистру R1, например ADD R1.A
Тогда при каждом шаге команда должна увеличиваться на 4. Таким образом,
после одного шага команда будет выглядеть следующим образом; ADD R1.A+4 и так далее до завершения цикла.
Программа, которая сама изменяется подобным образом, называется самоизменяющейся программой. Эта идея была предложена Джоном фон Нейманом и применялась в старых компьютерах, где не было косвенной регистровой адресации. В настоящее время самоизменяющиеся программы считаются неудобными и очень трудными для понимания. Кроме того, их выполнение нельзя разделить между несколькими процессорами. Они даже не могут правильно выполняться на машинах с разделенной кэш-памятью первого уровня, если в кэш-памяти команд нет специальной схемы для обратной записи (поскольку разработчики предполагали, что программы сами себя не изменяют).
Индексная адресация
Часто нужно уметь обращаться к словам памяти по известному смещению. Подобные примеры мы видели в машине IJVM, где локальные переменные определяются по смещению от регистра LV. Обращение к памяти по регистру и константе смещения называется индексной адресацией.
В машине IJVM при доступе к локальной переменной используется указатель
ячейки памяти (LV) в регистре плюс небольшое смещение в самой команде, как показано на рис. 4.14, а. Есть и другой способ: указатель ячейки памяти в команде и небольшое смещение в регистре. Чтобы показать, как это работает, рассмотрим следующий пример. У нас есть два одномерных массива А и В по 1024 слова в каждом. Нам нужно вычислить А, И Bi для всех пар, а затем соединить все эти 1024 логических произведения операцией ИЛИ, чтобы узнать, есть ли в этом наборе хотя бы одна пара, не равная нулю. Один из вариантов - поместить адрес массива А в один регистр, а адрес массива В - в другой регистр, а затем последовательно перебирать элементы массивов, аналогично тому, как мы делали в предыдущей программе (см. листинг 5.1). Такая программа, конечно же, будет работать, но ее можно усовершенствовать, как показано в листинге 5.2.
Здесь нам требуется 4 регистра:
1. R1 - содержит результаты суммирования логических произведений.
2. R2 - индекс i, который используется для перебора элементов массива.
3. R3 - константа 4096. Это самое маленькое значение i, которое не используется.
4. R4 - временный регистр для хранения каждого произведения.
После инициализации регистров мы входим в цикл из шести команд. Команда напротив LOOP вызывает элемент Ai в регистр R4. При вычислении источника здесь используется индексная адресация. Регистр (R2) и константа (адрес элемента А) складываются, и полученный результат используется для обращения к памяти. Сумма этих двух величин поступает в память, но не сохраняется ни в одном из видимых пользователем регистров. Запись
MOV R4.ACR2) означает, что для определения пункта назначения используется регистровая адресация, где R4 - это регистр, а для определения источника используется индексная адресация, где А - это смещение, a R2 - это регистр. Если А имеет значение, скажем, 124300, то соответствующая машинная команда будет выглядеть так, как показано на рис. 5.13.
Во время первого прохождения цикла регистр R2 принимает значение 0 (поскольку регистр инициализируется таким образом), поэтому нужное нам слово АО находится в ячейке с адресом 124300. Это слово загружается в регистр R4. При следующем прохождении цикла R2 принимает значение 4, поэтому нужное нам слово А1 находится в ячейке с адресом 124304 и т. д.
Как мы говорили раньше, здесь смещение - это указатель ячейки памяти, а значение регистра - это небольшое целое число, которое во время вычисления меняется. Такая форма требует, чтобы поле смещения в команде было достаточно большим для хранения адреса, поэтому такой способ не очень эффективен. Тем не менее этот способ часто оказывается самым лучшим.
Относительная индексная адресация
В некоторых машинах применяется способ адресации, при котором адрес вычисляется путем суммирования значений двух регистров и смещения (смещение факультативно). Такой подход называется относительной индексной адресацией. Один из регистров - это база, а другой - это индекс. Такая адресация очень удобна при следующей ситуации. Вне цикла мы могли бы поместить адрес элемента А в регистр R5, а адрес элемента В в регистр R6. Тогда мы могли бы заменить две первые команды цикла LOOP на
LOOP: MOV R4,(R2+R5) AND R4,(R2+R6)
Было бы идеально, если бы существовал способ адресации по сумме двух регистров без смещения. С другой стороны, даже команда с 8-битным смещением была бы большим достижением, поскольку мы оба смещения могли бы установить на 0. Однако если смещения всегда составляют 32 бита, тогда мы ничего не выиграем, используя такую адресацию. На практике машины с такой адресацией обычно имеют форму с 8-битным и 16-битным смещением.
Стековая адресация
Мы уже говорили, что очень желательно сделать машинные команды как можно короче. Конечный предел в сокращении длины адреса - это команды без адресов. Как мы видели в главе 4, безадресные команды, например IADD, возможны при наличии стека. В этом разделе мы рассмотрим стековую адресацию более подробно.
Обратная польская запись
В математике существует древняя традиция помещать оператор между операндами (х+у), а не после операндов (ху+). Форма с оператором между операндами называется инфиксной записью. Форма с оператором после операндов называется постфиксной или обратной польской записью в честь польского логика Я. Лукасевича (1958), который изучал свойства этой записи. Обратная польская запись имеет ряд преимуществ над инфиксной записью для выражения алгебраических формул. Во-первых, любая формула может быть выражена без скобок. Во-вторых, она удобна для вычисления формул в машинах со стеками. В-третьих, инфиксные операторы имеют приоритеты, которые произвольны и нежелательны. Например, мы знаем, что axb+c значит (axb)+c, а не ах (Ь+с), поскольку произвольно было определено, что умножение имеет приоритет над сложением. Но имеет ли приоритет сдвиг влево над логической операцией И? Кто знает? Обратная польская запись устраняет такие недоразумения. Существует несколько алгоритмов для превращения инфиксных формул в обратную польскую запись. Ниже изложена переделка идеи Э. Дейкстры. Предположим, что формула состоит из следующих символов: переменных, двухоперандных операторов +, -, *, /, а также левой и правой скобок. Чтобы отметить конец формулы, мы будем вставлять символ -L после последнего символа одной формулы и перед первым символом следующей формулы.
На рис. 5.14 нарисована железная дорога из Нью-Йорка в Калифорнию с раз-
вилкой, ведущей в Техас. Каждый символ формулы представлен одним вагоном. Поезд движется на запад (налево). Перед развилкой каждый вагон должен останавливаться и узнавать, должен ли он двигаться прямо в Калифорнию, или ему нужно по пути заехать в Техас. Вагоны, содержащие переменные, всегда направляются Калифорнию и никогда не едут в Техас. Вагоны, содержащие все прочие символы, должны перед вхождением на развилку узнавать о содержимом ближайшего вагона, отправившегося в Техас.
В таблице на рис. 5.15 показана зависимость ситуации от того, какой вагон отправился последним в Техас и какой вагон находится у развилки. Первый 1 всегда отправляется в Техас. Числа соответствуют следующим ситуациям:
1. Вагон на развилке направляется в Техас.
2. Последний вагон, направившийся в Техас, разворачивается и направляется
в Калифорнию.
3. Вагон, находящийся на развилке, и последний вагон, отправившийся в Техас, угоняются и исчезают (то есть оба удаляются).
4. Остановка. Символы, находящиеся в Калифорнии, представляют собой формулу в обратной польской записи, если читать слева направо.
5. Остановка. Произошла ошибка. Изначальная формула была некорректно
сбалансирована.
После каждого действия производится новое сравнение вагона, находящегося
у развилки (это может быть тот же вагон, что и в предыдущем сравнении, а может быть следующий вагон), и вагона, который на данный момент последним ушел на Техас. Этот процесс продолжается до тех пор, пока не будет достигнут шаг 4. Отметим, что линия на Техас используется как стек, где отправка вагона в Техас - это помещение элемента в стек, а разворот вагона, отправленного в Техас, в сторону Калифорнии - это выталкивание элемента из стека.
Порядок переменных в инфиксной и обратной польской записи одинаков. Однако порядок операторов не всегда один и тот же. В обратной польской записи операторы появляются в том порядке, в котором они будут выполняться. В табл. 5.5 даны примеры инфиксных формул и их эквивалентов в обратной польской записи.
Вычисление формул в обратной польской записи
Обратная польская запись - идеальная запись для вычисления формул на компьютере со стеком. Формула состоит из п символов, каждый из которых является или операндом, или оператором. Алгоритм для вычисления формулы в обратной польской записи с использованием стека прост. Нужно просто прочитать обратную польскую запись слева направо. Если встречается операнд, его нужно поместить в стек. Если встречается оператор, нужно выполнить соответствующую команду. В таблице 5.6 показано вычисление выражения (8+2x5)/(1+3x2-4) в машине JVM. Соответствующая формула в обратной польской записи выглядит следующим образом:
825х+132х+4-/
В таблице мы ввели команды умножения и деления IMUL и IDIV. Число на вершине стека - это правый операнд (а не левый). Это очень важно для операций деления и вычитания, поскольку порядок операндов в данном случае имеет значение (в отличие от операций сложения и умножения). Другими словами, команда I0IV определяется следующим образом: сначала в стек помещается числитель, потом знаменатель, и тогда выполнение операции дает правильный результат. Отметим, что преобразовать обратную польскую запись в код (I)JVM очень легко: нужно просто просканировать формулу в обратной польской записи и выдавать одну команду с каждым символом. Если символ является константой или переменной, нужно выдавать команду помещения этой константы или переменной в стек. Если
символ является оператором, нужно выдавать команду для выполнения данной операции.
Способы адресации для команд перехода
До сих пор мы рассматривали только те команды, которые оперируют с данными. Командам перехода (а также командам вызова процедур) также нужны особые способы адресации для определения целевого адреса. Способы, о которых мы говорили в предыдущих разделах, работают и для большинства команд перехода. Один из возможных вариантов - прямая адресация, когда целевой адрес просто полностью включается в команду.
Другие способы адресации тоже имеют смысл. Косвенная регистровая адресация позволяет программе вычислять целевой адрес, помещать его в регистр, а затем переходить туда. Такой способ дает максимальную гибкость, поскольку целевой адрес вычисляется во время выполнения программы. Но он также предоставляет огромные возможности для появления ошибок, которые практически невозможно найти.
Индексная адресация, при которой известно смещение от регистра, также является вполне разумным способом. Этот способ обладает теми же свойствами, что и косвенная регистровая адресация.
Еще один вариант - относительная адресация по счетчику команд. В данном
случае для получения целевого адреса смещение (со знаком), находящееся в самой команде, прибавляется к программному счетчику. По сути, это индексная адресация, где в качестве регистра используется PC.
Ортогональность кодов операций и способов адресации
С точки зрения программного обеспечения, команды и способы адресации должны иметь регулярную структуру, число форматов команд должно быть минимальным. При такой структуре компилятору гораздо проще порождать нужный код. Все коды операций должны допускать все способы адресации, где это имеет смысл. Более того, все регистры должны быть доступны для всех типов регистров (включая указатель фрейма (FP), указатель стека (SP) и программный счетчик (PC)). Рассмотрим 32-битные форматы команд для трехадресной машины (рис. 5.16). Здесь поддерживаются до 256 кодов операций. В формате 1 каждая команда имеет два входных регистра и один выходной регистр. Этот формат используется для всех арифметических и логических команд. Неиспользованное 6-битное поле в конце формата может использоваться для дальнейшей дифференциации команд. Например, можно иметь один код для всех операций с плавающей точкой, а различаться эти операции будут по дополнительному полю. Кроме того, если установлен бит 23, тогда используется формат 2, а второй операнд уже не является регистром, а является 13-битной непосредственной константой со знаком. Команды LOAD и STORE тоже могут использовать этот формат для обращения к памяти при индексном способе адресации.
Дата публикования: 2014-10-17; Прочитано: 899 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!