Процессор

Процессор

Способы адресации при адресной организации памяти

Понятие косвенной адресации

Пусть какой-нибудь способ адресации (1) указывает место положения операнда (неважно, регистр процессора или адрес в памяти). Можно представить себе другой способ адресации (2), во всем аналогичный способу (1) за исключением того, что в указываемом месте расположен не сам операнд, а его адрес, т.е. номер ячейки в ОЗУ, где находится операнд. Тогда будем говорить, что способ (1) - прямой, а соответствующий ему способ (2) - косвенный по отношению к способу (1). В символике языков ассемблера для обозначения косвенности используются скобки или символ @.


1) add ax,loc - эта ассемблерная запись означает "прибавить к содержимому регистра AX содержимое ячейки памяти, адрес которой обозначен символическим именем LOC”.

2) ADD AX,(LOC)или ADD AX,@LOC - в этой записи используется косвенная адресация, запись означает "прибавить к содержимому регистра AX содержимое ячейки памяти, адрес которой хранится в ячейке памяти с символическим именем LOC”.


Можно провести аналогию между использованием косвенной адресации в языке ассемблера и использованием указателей в языке Си. В строке iA+ = iB ; обращение к операнду iB произойдет с использованием прямой адресации. Строка iA+ = *piB; использует косвенную адресацию переменной через указатель piB = &iB. По индукции можно представить себе двойную, тройную косвенность и т.п. Существовали компьютеры, в которых была реализована косвенность произвольной глубины. Рассмотрим теперь конкретно различные способы адресации. При рассмотрении использованы мнемоники ассемблера для процессоров i*86. Используемый в команде способ адресации кодируется в адресном поле операнда. За исключением непосредственной и абсолютной адресации, адресное поле указывает на адресный регистр (может быть на несколько) и задает способ вычисления адреса с участием содержимого этого регистра (ов).

 

Неявная (inherent) адресация

Этот термин относится не к способу вычисления адреса (местоположения) операнда, а к способу обозначения этого местоположения в синтаксисе ассемблера. Например, команда "поместить в стек”: push ax.

Никаких вычислений для определения адреса операнда делать не надо, операнд выбирается из ОЗУ вслед за командой. Операнд может быть разной длины (занимать разное число ячеек/байтов).

 

Абсолютная или прямая адресация

В команде за КОП помещается заранее известный адрес операнда. Обратите внимание, что абсолютная адресация является косвенным вариантом для непосредственной адресации. add cx, [123] ; содержимое регистра складывается с содержимым ячейки, абсолютный адрес которой входит в состав команды (см. рисунок).

Для выборки операнда нужно дополнительное обращение к ОЗУ.

 

Регистровая адресация

Операнд находится в одном из регистров процессора. sub bx, si ; вычитаются два операнда, находящиеся в регистрах процессора (см. рисунок ниже).

Обращение к регистру процессора гораздо быстрее, чем к ячейке ОЗУ. Код регистра занимает более короткое поле в команде, чем операнд или адрес.

 

Косвенно-регистровая адресация

Адрес операнда находится в одном из регистров процессора. Во многих процессорах регистры специализированы, и адрес может находиться не в любом из них (см. рисунок ниже).
mov [si], 12

Указатель регистра Ri занимает более короткое поле чем адрес. Тот факт, что адрес операнда находится в регистре, позволяет вычислять или модифицировать этот адрес, при этом один и тот же участок программы может обрабатывать разные элементы данных (находящиеся в разных адресах).
Вот фрагмент, суммирующий в регистре ax элементы массива слов:
mov si, "начальный адрес массива"
mov cx, "количество элементов массива"
ckl add ax, [si]; прибавляем следующий элемент
add si, 2; модифицируем адрес в массиве
loop ckl; организуем цикл
Выделенные команды эквивлентны Си-фрагменту sum += *(piMas++); .

 

Автоинкрементная (автодекрементная) адресация

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

В ходе выполнения команды с данным типом адресации после (либо до) выборки операнда из ОЗУ содержимое регистра Ri модифицируется: к его старому содержимому прибавляется число L - длина операнда в байтах (в минимальных адресуемых единицах). Таким образом после этой модификации в Ri оказывается адрес следующего элемента данных. Автоинкрементная адресация позволяет обращаться к элементам данных, расположенных в памяти подряд по возрастанию адресов (например, к элементам массива). При автодекрементной адресации сложение с L заменяется на вычитание, и элементы данных перебираются в порядке убывания их адресов (см. рисунок ниже).

Величина L, на которую происходит увеличение или уменьшение адреса, в простейшем случае равна минимальной адресуемой единице (байту). Однако, если процессор поддерживает операции с операндами разной длины (байт, слово, двойное слово,...), то и автоиндексация/ декремент может быть реализован на 1, на 2, на 4, ...

Если модификация адресного регистра происходит после обращения к операнду, такую разновидность называют постинкрементной адресацией, если модификация адреса выполняется перед обращением к операнду - преинкрементной. Наиболее часто в процессоре реализуется сочетание постинкрементной и предекрементной адресации. В процессорах i*86 автоиндексная адресация в общем виде (т.е. для использования в произвольной команде) не реализована. Однако в неявном виде она использована в командах операций со строками. Например, при выполнении команды LODS происходит загрузка в регистр AL (или AX или EAX) содержимого ячейки памяти, на которую указывает адресный регистр SI, после чего содержимое регистра SI автоматически модифицируется.

 

Многокомпонентные способы формирования адреса

Многокомпонентное формирование адреса тесно связаны с идеей относительной адресации. Если отсчитывать адреса объектов программы от места, жестко привязанного к программе (например, от ее начала), то эти относительные значения не меняются, куда бы ни была загружена программа. То же можно сказать и про любую часть программы (например, про участок памяти с данными). Как же можно осуществить такую относительную адресацию?
Для этого можно формировать адрес из двух слагаемых:


•Одно (базовый адрес) зависит от того, куда загружаем программу, задается перед загрузкой, и в течение всего времени выполнения программы остается неизменным (но от загрузки к загрузке может изменяться).


•Второе (относительный адрес) представляет собой разность базового адреса и абсолютного адреса объекта. Адрес задается не как абсолютное значение, а как смещение относительно какого-либо базового значения.


Хочется обеспечить позиционную независимость (без пересчета адресных частей команд). Если вспомним, что после трансляции загружаемый (двоичный) образ программы не меняется, можем высказать идею отсчитывать адреса относительно чего-то в самой программе. Идея формировать адрес как комбинацию (сумму или конкатенацию) нескольких компонент используется как в способах адресации, так и при трансляции адресов. Между понятиями "способ адресации" и "процедура трансляции адреса" непросто провести более-менее четкую границу. Та часть преобразования адресной информации, которая изменяется от одной команды к другой - способ адресации. Трансляция адреса - часть преобразования адреса, одинаковая для разных команд. Трансляцией адреса тоже можно управлять (например, включить или выключить трансляцию страниц), однако это переключение выполняется редко, после чего значительная часть программы выполняется в заданном единожды режиме.

 

Многокомпонентные способы адресации

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


•а) При вычислении адреса элемента в сложной структуре данных часть действий по этому вычислению можно возложить на адресную арифметику. Например, требуется определить адрес элемента двумерного массива с индексами i, j, если начальный адрес массива AddrM, длина строки массива LStr, а длина одного элемента LElm. Формула для вычисления адреса имеет вид:
Addr(i,j) = AddrM + LStr * (i-1) * LElm + (j-1) * LElm
При использовании многокомпонентной адресации, использующей три компоненты (например, базово-индексной адресации со смещением в процессорах i*86) с компонентами можно связывать адрес начала массива, смещение в массиве от начала до нужной строки и смещение в строке до нужного элемента. Сложение компонент выполнит автоматически адресная арифметика.

•б) Компонента адреса, хранящаяся в регистре или в команде, может быть короче полного адреса (и, значит, занимать меньше места). Это позволит адресовать более коротким полем память большего объема (см. например страничную адресацию).


•в) Возможно в любой момент перемещение в памяти блока объектов с одновременным изменением содержимого базового регистра, участвующего в формировании всех адресов при доступе к этим объектам..


•г) Использование в качестве адресной компоненты счетчика команд автоматически дает позиционную независимость (статическую и динамическую перемещаемость).

Страничная адресация

Это, пожалуй, простейший из многокомпонентных способов. Адрес разбивается на две части, которые объединяются не сложением, а конкатенацией (соединением двух частей числа). Старшая часть адреса указывает номер страницы. Она либо хранится в специальном регистре страницы (общий случай), либо берется из счетчика команд (адресация на текущую страницу), либо фиксирована (часто так делается адресация на нулевую страницу, которая используется для специальных целей). В команде (или в регистре) указывается только младшая часть адреса. Таким образом удается уменьшить длину команды.

 

Относительная адресация

В качестве одной из компонент при формировании адреса используется счетчик команд. При этом способе адресации операнд отстоит в памяти от команды на фиксированную величину. Иными словами, операнд указывается путем задания его смещения (displacement) в памяти относительно обращающейся к операнду команды. Использование только относительной адресации делает программы позиционно- независимыми, т.е. их можно перемещать в памяти без каких бы то ни было изменений в тексте программы. Относительная адресация используется во многих процессорах в командах условного ветвления, причем чаще всего смещение имеет формат "байт со знаком" и способно задать переход в диапазоне +127 -128 байтов.

Стековый доступ к памяти

Стековый доступ к памяти происходит в большинстве процессоров в следующих ситуациях:
1) При выполнении команд стекового доступа: "поместить в стек" pushили "извлечь из стека" pop.
2) При выполнении команды вызова подпрограммы и при возврате из нее.
3) При входе в прерывание и при возврате из прерывания.


Положение стека в адресуемой памяти определяется содержимым указателя стека. Поскольку указатель стека программно доступен, программист может задать его значение обычной командой пересылки. Например, команда mov sp,#1000h задает положение стека, начиная с адреса 1000h. При стековом доступе содержимое указателя стека используется как адрес операнда-приемника при записи в стек или как адрес операнда- источника при считывании из стека. При обращении к стеку автоматически модифицируется и содержимое указателя стека, чтобы обеспечить следующее обращение к очередной ячейке стека. Используя ранее введенную терминологию, можно сказать, что обращение к стеку происходит с использованием косвенно-регистровой адресации через указатель стека с автоиндексацией (см. таблицу ниже). В разных процессорах стековый доступ может быть реализован по-разному в нескольких аспектах:

1. Направление роста стека. Если при записи в стек, содержимое указателя стека автоматически увеличивается (и, соответственно, при считывании автоматически уменьшается), то говорят, что стек растет в сторону увеличения адресов. В противоположном случае говорят, что стек растет в сторону уменьшения адресов.
2. Если модификация указателя стека выполняется до записи и соответственно после считывания, то указатель стека всегда указывает на последнюю занятую ячейку стека. Наоборот, если модификация производится после записи и до считывания, указатель стека всегда указывает на первую свободную ячейку стека.

 

Если запись в стек происходит с преиндексацией, то считывание должно происходить с постиндексацией (и наоборот). Распространение различных видов адресации (см. таблицу ниже) зависит от типа АСК. Достаточно ясна ситуация с RISC архитектурой. Из самой идеи подхода вытекает преимущественный способ адресации: регистровая. Для аккумуляторной архитектуры главные способы адресации - прямая и непосредственная. В таблице показана частота применения разных способов адресации на двух тестовых программах для процессоров типа Intel 80x86. Видно, что наиболее активно используется прямая и базово-регистровая адресации, хотя интенсивность использования различных способов тесно связана с решаемой задачей.

 

Стековая архитектура

Стеком называется память, состоящая из взаимосвязанных ячеек, взаимодействующих по принципу "последним вошел - первым вышел" (LIFO, Last In First Out).

Верхнюю ячейку называют вершиной стека. Для работы со стеком предусмотрены две операции: рush (проталкивание данных в стек) и рор (выталкивание данныx из стека). Запись возможна только в верхнюю ячейку стека, при этом вся хранящаяся в стеке информация предварительно проталкивается на одну позицию вниз. Чтение допустимо также только из вершины стека. Извлеченная информация удаляется из стека, а оставшееся его содержимое продвигается вверх. В вычислительных машинах, где реализована АСК на базе стека (их обычно называют стековыми), операнды перед обработкой помещаются в две верхних ячейки стековой памяти. Результат операции заносится в стек.

В большинстве процессоров стек (т.е. память со стековым доступом) организован в участке обычной памяти с адресной организацией. Для этого в процессоре имеется специальный регистр - указатель стека (Stack Pointer SP). Этот регистр содержит адрес памяти того участка, в который будет осуществляться стековый доступ, а, говоря более точно, адрес "верхушки стека". Указатель стека обычно программно доступен, то есть к нему можно производить обращение как к любому другому регистру.

При описании вычислений с использованием стека обычно используется иная форма записи математических выражений, известная как обратная польская запись (обратная польская нотация), которую предложил польский математик Я. Лукашевич. Особенность ее в том, что в выражении отсутствуют скобки, а знак операции располагается не между операндами, а следует за ними (постфиксная форма). Последовательность операций определяется их приоритетами. Выражение а = а + b + а х с в постфиксной форме будет записано в виде: а = а b + а с х +.

АСК на основе стека долгое время считался неперспективным. Однако в послнеднее время возрождается интерес к стековой архитектуре ВМ. Это связано с популярностью языкa Java и расширением сферы применения языка Forth, семантике которых наиболее близка именно стековая архитектура.

Команды пересылки

Пересылки общего назначения

Пересылки общего назначения MOV, L**, LD*, LOD* (от Load - загрузить), ST* (от Store - сохранить). Передают слово/байт данных из одной части ЭВМ в другую без изменения. Иногда в эту группу включают также и команды ввода-вывода для ЭВМ у которых область адресов внешних устройств включена в общее адресное пространство.

Пересылки из/в стек

Пересылки из/в стек: PUSH (втолкнуть), POP (вынуть). Обычно отличаются тем, что используют стековую адресацию (задаваемую неявно.

Пересылки двоичных слов

Пересылки двоичных слов, представляющих собой адреса операндов или части (компоненты) адресов. Для операций с адресами нередко в процессор вводят специальные команды. Это связано с тем, что разрядность адреса в процессоре не всегда совпадает с разрядностью АЛУ и регистров.

Пересылки между элементами вычислительного ядра

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

Проверка условий, флаги и набор команд ветвления

Сравнение в ЭВМ используется для организации последующего ветвления алгоритма (условного перехода в программе) в зависимости от результата сравнения. Сравнение можно производить по условиям:

  • а) равно / неравно;
  • б) больше / меньше.

Условие а) всегда осмысленно и формально означает, что все биты сравниваемых операндов одинаковы. Семантика условия б) понятна для данных, которые неким образом упорядочены, таких, как числа или символы алфавита. Для такого вида данных, как битовые поля, не всегда понятно, что такое "больше / меньше".

Сравнение в процессоре происходит по одной из двух схем:

  1. Сравнение операнда с нулем (его можно произвести специальной командой “проверка”: в системе команд х86 - команда test a, b).
  2. Сравнение двух операндов между собой (вычитанием и последующим сравнением результата с нулем)

Для сравнения двух чисел можно использовать команды вычитания. Кроме того, обычно в системе команд есть специальные команды для сравнения. В i*86 это команда cmp a,b - она делает вычитание a - b, по результату операции модифицируются все 4 основных флага - cf, of, zf, sf, после чего результат вычитания теряется, а операнды сохраняются неизменными.

Для сравнения с нулем есть специальные команды "проверить операнд" (в i*86 - команда test a, b), а, кроме того, - флаги zf и sf могут устанавливаться при выполнении других команд (таких, как загрузки и пересылки).

После выполнения команды, осуществляющей сравнение (и переустанавливающей флаги), надо осуществить ветвление. Для этого в процессоре обычно существует большая группа команд условного ветвления, которое происходит (или нет) в зависимости от состояний тех или иных флагов. В группе команд ветвления можно выделить три подгруппы (Таблица 1, Таблица 2, Таблица 3).

 

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

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

 

Кодирование двухоперандной команды

В этой сложной структуре КОП может занимать один или два байта. Адресная часть команды может либо вообще отсутствовать, либо включать в свой состав от одного (ModR/M) до 12 байтов.

Адресная информация, закодированная в такой сложной команде, может содержать следующие сведения:

  • сколько операндов использует команда (два, один или ни одного);
  • расположен ли операнд в регистре или в памяти;
  • если в регистре, то в каком;
  • если операнд в команде, сколько для него там отведено места (immеdiate);
  • если операнд в памяти, то по какой схеме следует определять его адрес;
  • при многокомпонентной адресации, в адресной части может находиться поле для части адреса (displacement);
  • и др.

Префикс

Длина префикса 1 байт. Имеется всего 5 префиксов для Х86

 

Префиксы X86

Код операции

КОП - код операции. Длина 1 байт. 0-й бит КОП во многих (но не во всех) командах показывает, производится ли операция со словом (=1) или с байтом (=0). 1-й бит КОП в двухадресных командах указывает, какой из операндов является приемником.

Постбайт адресации

Длина 1 байт. Постбайт адресации показывает, где находятся операнды. Один из операндов (первый) может быть расположен в регистре (регистровая адресация) или в произвольной ячейке ОЗУ (все способы адресации кроме непосредственной). Второй операнд может находиться в теле команды (непосредственная адресация) или в регистре (регистровая адресация). Каждый из операндов может быть как источником, так и приемником (за исключением непосредственной адресации: непосредственный операнд может быть только источником). Структура системы адресации несимметрична.

 

Поля mod и r/m задают место расположения первого операнда. Поле reg задает положение второго операнда.

Значения поля mod:

11 - операнд в регистре (при остальных mod операнд в ОЗУ, а регистры, на которые указывают поля mod и r/m, содержат компоненты адреса операнда);
10 - смещение два байта (без знака);
01 - смещение один байт (со знаком);
00 - смещение в команде отсутствует.

Смещение

Длина 1 байт (при mod-01) или 2 байта(при mod=10).

Непосредственный операнд

Длина 1 или 2 байта.

Рисунок иллюстрирует различные способы адресации.

 

В 32-х разрядных процессорах для кодирования расширенных регистров появился в формате после постбайта SIB-байт. Байт SIB включает в себя следующие поля:

  • Поле ss, которое занимает 2 старших бита байта, определяет масштабный коэффициент.
  • Поле index, которое занимает следующие 3 бита за полем ss, задает для индексного регистра номер регистра.
  • Поле base, которое занимает младшие три бита байта, задает номер базового регистра.

 

Подкатегории

Яндекс.Метрика