Реклама:

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

Чтобы понять, почему может быть полезно использовать разные слова при каждом выполнении команды, представим себе цикл, который проходит по 1024-элементному одномерному массиву целых чисел для получения в регистре Ш суммы элементов. Вне этого цикла какой-то другой регистр, например 112, может указывать на первый элемент массива, а еще один регистр, например КЗ, - на первый адрес после массива. Массив содержит 1024 целых числа по 4 байта каждое. Если массив начинается с элемента Д то первый адрес после массива будет А + 4096. Типичная программа на ассемблере, выполняющая это вычисление для двухадресной машины, показана в листинге 5.1.

Листинг 5.1. Программа на ассемблере для вычисления суммы элементов массива

MOV R1,#0 ; накопление суммы в R1, изначально О

MOV R2JA ; R2 = адрес массива А

MOV R3JA+4096 ; R3 = адрес первого слова после А

LOOP: ADD R1.(R2) ; получение операнда через регистр R2

ADD R2,#4 ; увеличение R2 на одно слово (4 байта)

CMP R2.R3 ; проверка завершения

BLT LOOP : если R2 < R3, продолжать цикл

В этой маленькой программе мы использовали несколько режимов адресации. В первых трех командах выполняется регистровая адресация первого операнда (целевого) и непосредственная адресация второго (константа, обозначаемая символом #). Вторая команда помещает в R2 не содержимое элемента А, а элемент А. Именно это и сообщает ассемблеру знак #. Сходным образом третья команда помещает в R3 первое слово после массива.

Интересно отметить, что само тело цикла не содержит каких-либо адресов памяти. В четвертой команде используются регистровая и косвенная адресация. В пятой команде применяются регистровая и непосредственная адресация, в шестой - оба раза регистровая. Команда BLT могла бы использовать адрес памяти, однако более привлекательным является определение адреса с помощью 8-разрядного смещения, связанного с самой командой BLT. Таким образом, вообще без обращения по адресам памяти, мы получили короткий и быстрый цикл. Кстати, эта программа предназначена для Pentium 4, только мы переименовали команды и регистры и для простоты изменили запись.

Теоретически есть еще один способ выполнения этого фрагмента без косвенной регистровой адресации. Цикл мог бы содержать команду для прибавления А к регистру R1, например:

ADD Rl, А

Тогда при каждом шаге команда должна увеличиваться на 4. Таким образом, после одного шага команда будет выглядеть следующим образом:

ADD Rl, А + 4

И далее аналогично до завершения цикла.

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

Регистровая адресация || Оглавление || Индексная адресация