какой способ адресации имеет наиболее компактный код
Система кодирования команд. Способы адресации
Способы адресации
Решить проблему сокращения разрядности команды только за счет сокращения количества указываемых в команде операндов и применения регистровой памяти невозможно. Этой же цели служит использование различных способов адресации операндов. Кроме того, применение нескольких способов адресации повышает гибкость программирования, так как в каждом конкретном случае позволяет обеспечить наиболее рациональный способ доступа к информации в памяти.
К основным способам адресации относятся следующие: прямая, непосредственная, косвенная, относительная.
где Аi – код, содержащийся в i-м адресном поле команды.
Допускается использование прямой адресации при обращении как к основной, так и к регистровой памяти.
Непосредственная адресация. В команде содержится не адрес операнда, а непосредственно сам операнд ( рис. 11.5):
Косвенная адресация ( рис. 11.6). Адресная часть команды указывает адрес ячейки памяти (рис. 11.6,а) или номер регистра (рис. 11.6,б), в которых содержится адрес операнда:
Применение косвенной адресации операнда из оперативной памяти при хранении его адреса в регистровой памяти существенно сокращает длину поля адреса, одновременно сохраняя возможность использовать для указания физического адреса полную разрядность регистра.
Косвенная адресация не применяется по отношению к операндам, находящимся в регистровой памяти.
Рассмотрим два примера.
Главный недостаток относительной адресациии – большое время вычисления физического адреса операнда. Но существенное преимущество этого способа адресации заключается в возможности создания «перемещаемых» программ – программ, которые можно размещать в различных частях памяти без изменения команд программы. То же относится к программам, обрабатывающим по единому алгоритму информацию, расположенную в различных областях ЗУ. В этих случаях достаточно изменить содержимое базового адреса начала команд программы или массива данных, а не модифицировать сами команды. По этой причине относительная адресация облегчает распределение памяти при составлении сложных программ и широко используется при автоматическом распределении памяти в мультипрограммных вычислительных системах.
Методы адресации
Методы адресации — в вычислительной технике способы указания на определённую ячейку (ячейки) памяти ЭВМ процессору с целью записи, чтения данных или передачи управления.
Содержание
Задача адресации
Задача адресации заключается в указании на текущую ячейку памяти, к которой происходит обращение процессора. Адрес текущей ячейки как правило записывается в один или несколько регистров процессора. Методы адресации памяти имеют особое значение при программировании на языке низкого уровня (языке ассемблера). Существует два вида адресации: прямая и косвенная.
Способы адресации
Подразумеваемый операнд
В команде может не содержаться явных указаний об операнде; в этом случае операнд подразумевается и фактически задается кодом операции команды.
Подразумеваемый адрес
В команде может не содержаться явных указаний об адресе участвующего в операции операнда или адреса, по которому должен быть размещен результат операции, но этот адрес подразумевается.
Непосредственная адресация
В команде содержится не адрес операнда, а непосредственно сам операнд. При непосредственной адресации не требуется обращения к памяти для выборки операнда и ячейки памяти для его хранения. Это способствует уменьшению времени выполнения программы и занимаемого ею объема памяти. Непосредственная адресация удобна для хранения различного рода констант.
Прямая адресация
Адрес указывается непосредственно в виде некоторого значения, все ячейки располагаются на одной странице. Преимущество этого способа в том, что он самый простой, а недостаток — в том, что разрядность регистров общего назначения процессора должна быть не меньше разрядности шины адреса процессора.
Относительная (базовая) адресация
При этом способе адресации исполнительный адрес определяется как сумма адресного кода команды и базового адреса, как правило хранящегося в специальном регистре — регистре базы.
Относительная адресация позволяет при меньшей длине адресного кода команды обеспечить доступ к любой ячейке памяти. Для этого число разрядов в базовом регистре выбирают таким, чтобы можно было адресовать любую ячейку оперативной памяти, а адресный код команды используют для представления лишь сравнительно короткого «смещения». Смещение определяет положение операнда относительно начала массива, задаваемого базовым адресом.
Укороченная адресация
В адресном поле командного слова содержатся только младшие разряды адресуемой ячейки. Дополнительный указательный регистр.
Регистровая адресация
Регистровая адресация является частным случаем укороченной. Применяется, когда промежуточные результаты хранятся в одном из рабочих регистров центрального процессора. Поскольку регистров значительно меньше чем ячеек памяти, то небольшого адресного поля может хватить для адресации.
Косвенная адресация
Адресный код команды в этом случае указывает адрес ячейки памяти, в которой находится адрес операнда или команды. Косвенная адресация широко используется в малых и микроЭВМ, имеющих короткое машинное слово, для преодоления ограничений короткого формата команды (совместно используются регистровая и косвенная адресация).
Адресация слов переменной длины
Эффективность вычислительных систем, предназначенных для обработки данных, повышается, если имеется возможность выполнять операции со словами переменной длины. В этом случае в машине может быть предусмотрена адресация слов переменной длины, которая обычно реализуется путем указания в команде местоположения в памяти начала слова и его длины.
Стековая адресация
Стековая память, реализующая безадресное задание операндов, особенно широко используется в микропроцессорах и Мини-ЭВМ.
Автоинкрементная и автодекрементная адресации
Поскольку регистровая косвенная адресация требует предварительной загрузки регистра косвенным адресом из оперативной памяти, что связано с потерей времени, такой тип адресации особенно эффективен при обработке массива данных, если имеется механизм автоматического приращения или уменьшения содержимого регистра при каждом обращении к нему. Такой механизм называется соответственно автоинкрементной и автодекрементной адресацией. В этом случае достаточно один раз загрузить в регистр адрес первого обрабатываемого элемента массива, а затем при каждом обращении к регистру в нем будет формироваться адрес следующего элемента массива.
При автоинкрементной адресации сначала содержимое регистра используется как адрес операнда, а затем получает приращение, равное числу байт в элементе массива. При автодекрементной адресации сначала содержимое указанного в команде регистра уменьшается на число байт в элементе массива, а затем используется как адрес операнда.
Автоинкрементная и автодекрементная адресации могут рассматриваться как упрощенный вариант индексации — весьма важного механизма преобразования адресных частей команд и организации вычислительных циклов, поэтому их часто называют автоиндексацией.
Индексация
Для реализуемых на ЭВМ методов решения математических задач и обработки данных характерна цикличность вычислительных процессов, когда одни и те же процедуры выполняются над различными операндами, упорядоченно расположенными в памяти. Поскольку операнды, обрабатываемые при повторениях цикла, имеют разные адреса, без использования индексации требовалось бы для каждого повторения составлять свою последовательность команд, отличающихся адресными частями.
Программирование циклов существенно упрощается, если после каждого выполнения цикла обеспечено автоматическое изменение в соответствующих командах их адресных частей согласно расположению в памяти обрабатываемых операндов. Такой процесс называется модификацией команд, и основан на возможности выполнения над кодами команд арифметических и логических операций.
Методы адресации
Методы адресации — в вычислительной технике способы указания на определённую ячейку (ячейки) памяти ЭВМ процессору с целью записи, чтения данных или передачи управления.
Содержание
Задача адресации
Задача адресации заключается в указании на текущую ячейку памяти, к которой происходит обращение процессора. Адрес текущей ячейки как правило записывается в один или несколько регистров процессора. Методы адресации памяти имеют особое значение при программировании на языке низкого уровня (языке ассемблера). Существует два вида адресации: прямая и косвенная.
Способы адресации
Подразумеваемый операнд
В команде может не содержаться явных указаний об операнде; в этом случае операнд подразумевается и фактически задается кодом операции команды.
Подразумеваемый адрес
В команде может не содержаться явных указаний об адресе участвующего в операции операнда или адресе, по которому должен быть размещен результат операции, но этот адрес подразумевается.
Непосредственная адресация
В команде содержится не адрес операнда, а непосредственно сам операнд. При непосредственной адресации не требуется обращения к памяти для выборки операнда и ячейки памяти для его хранения. Это способствует уменьшению времени выполнения программы и занимаемого ею объема памяти. Непосредственная адресация удобна для хранения различного рода констант.
Прямая адресация
Адрес указывается непосредственно в виде некоторого значения, все ячейки располагаются на одной странице. Преимущество этого способа в том, что он самый простой, а недостаток — в том, что разрядность регистров общего назначения процессора должна быть не меньше разрядности шины адреса процессора. Файл:DIrectAddressing.JPG
Относительная (базовая) адресация
При этом способе адресации исполнительный адрес определяется как сумма адресного кода команды и базового адреса, как правило хранящегося в специальном регистре — регистре базы.
Относительная адресация позволяет при меньшей длине адресного кода команды обеспечить доступ к любой ячейке памяти. Для этого число разрядов в базовом регистре выбирают таким, чтобы можно было адресовать любую ячейку оперативной памяти, а адресный код команды используют для представления лишь сравнительно короткого «смещения». Смещение определяет положение операнда относительно начала массива, задаваемого базовым адресом.
Укороченная адресация
В адресном поле командного слова содержатся только младшие разряды адресуемой ячейки. Дополнительный указательный регистр.
Регистровая адресация
Регистровая адресация является частным случаем укороченной. Применяется, когда промежуточные результаты хранятся в одном из рабочих регистров центрального процессора. Поскольку регистров значительно меньше чем ячеек памяти, то небольшого адресного поля может хватить для адресации.
Косвенная адресация
Адресный код команды в этом случае указывает адрес ячейки памяти, в которой находится адрес операнда или команды. Косвенная адресация широко используется в малых и микроЭВМ, имеющих короткое машинное слово, для преодоления ограничений короткого формата команды (совместно используются регистровая и косвенная адресация).
Адресация слов переменной длины
Эффективность вычислительных систем, предназначенных для обработки данных, повышается, если имеется возможность выполнять операции со словами переменной длины. В этом случае в машине может быть предусмотрена адресация слов переменной длины, которая обычно реализуется путем указания в команде местоположения в памяти начала слова и его длины.
Стековая адресация
Стековая память, реализующая безадресное задание операндов, особенно широко используется в микропроцессорах и Мини-ЭВМ.
Автоинкрементная и автодекрементная адресации
Поскольку регистровая косвенная адресация требует предварительной загрузки регистра косвенным адресом из оперативной памяти, что связано с потерей времени, такой тип адресации особенно эффективен при обработке массива данных, если имеется механизм автоматического приращения или уменьшения содержимого регистра при каждом обращении к нему. Такой механизм называется соответственно автоинкрементной и автодекрементной адресацией. В этом случае достаточно один раз загрузить в регистр адрес первого обрабатываемого элемента массива, а затем при каждом обращении к регистру в нем будет формироваться адрес следующего элемента массива.
При автоинкрементной адресации сначала содержимое регистра используется как адрес операнда, а затем получает приращение, равное числу байт в элементе массива. При автодекрементной адресации сначала содержимое указанного в команде регистра уменьшается на число байт в элементе массива, а затем используется как адрес операнда.
Автоинкрементная и автодекрементная адресации могут рассматриваться как упрощенный вариант индексации — весьма важного механизма преобразования адресных частей команд и организации вычислительных циклов, поэтому их часто называют автоиндексацией.
Индексация
Для реализуемых на ЭВМ методов решения математических задач и обработки данных характерна цикличность вычислительных процессов, когда одни и те же процедуры выполняются над различными операндами, упорядоченно расположенными в памяти. Поскольку операнды, обрабатываемые при повторениях цикла, имеют разные адреса, без использования индексации требовалось бы для каждого повторения составлять свою последовательность команд, отличающихся адресными частями.
Программирование циклов существенно упрощается, если после каждого выполнения цикла обеспечено автоматическое изменение в соответствующих командах их адресных частей согласно расположению в памяти обрабатываемых операндов. Такой процесс называется модификацией команд, и основан на возможности выполнения над кодами команд арифметических и логических операций.
Какой способ адресации имеет наиболее компактный код
Способом, или режимом адресации, называют процедуру нахождения операнда для выполняемой команды. Если команда использует два операнда, то для каждого из них должен быть задан способ адресации, причем режимы адресации первого и второго операнда могут как совпадать, так и различаться. Операнды команды могут находиться в разных местах: непосредственно в составе кода команды, в каком-либо регистре, в ячейке памяти; в последнем случае существует несколько возможностей указания его адреса. Строго говоря, способы адресации являются элементом архитектуры процессора, отражая заложенные в нем возможности поиска операндов. С другой стороны, различные способы адресации определенным образом обозначаются в языке ассемблера и в этом смысле являются разделом языка.
Следует отметить неоднозначность термина «операнд» применительно к программам, написанным на языке ассемблера. Для машинной команды операндами являются те данные (в сущности, двоичные числа), с которыми она имеет дело. Эти данные могут, как уже отмечалось, находиться в регистрах или в памяти. Если же рассматривать команду языка ассемблера, то для нее операндами (или, лучше сказать, параметрами) являются те обозначения, которые позволяют сначала транслятору, а потом процессору определить местонахождение операндов машинной команды. Так, для команды ассемблера
По отношению к командам ассемблера было бы правильнее использовать термин «параметры», оставив за термином «операнд» обозначение тех физических объектов, с которыми имеет дело процессор при выполнении машинной команды, однако обычно эти тонкости не принимают в расчет и, говоря об операндах команд языка, понимают в действительности операнды машинных команд.
В архитектуре современных 32-разрядных процессоров Intel предусмотрены довольно изощренные способы адресации; в МП 86 способов адресации меньше. В настоящем разделе будут описаны режимы адресации, используемые в МП 86.
В книгах, посвященных языку ассемблера, можно встретить разные подходы к описанию способов адресации: не только названия этих режимов, но даже и их количество могут различаться. Разумеется, способов адресации существует в точности столько, сколько их реализовано в процессоре; однако, режимы адресации можно объединять в группы по разным признакам, отчего и создается некоторая путаница, в том числе и в количестве имеющихся режимов. Мы будем придерживаться распространенной, но не единственно возможной терминологии.
Регистровая адресация
Операнд (байт или слово) находится в регистре. Этот способ адресации применим ко всем программно-адресуемым регистрам процессора.
inc СН ;Плюс 1 к содержимому СН
push DS ;DS сохраняется в стеке
xchg ВХ,ВР ;ВХ и ВР обмениваются содержимым
mov ES,АХ ;Содержимое АХ пересылается в ES
Непосредственная адресация
Операнд (байт или слово) указывается в команде и после трансляции поступает в код команды; он может иметь любой смысл (число, адрес, код ASCII), а также быть представлен в виде символического обозначения.
mov АН,40h ;Число 40h загружается в АН
mov AL,’*’ ;Код ASCII символа ‘*’ загружается в AL
int 21h ;Команда прерывания с аргументом 21h
limit = 528 ;Число 528 получает обозначение limit
mov CX,limit ;Число, обозначенное limit, загружается в СХ
Важным применением непосредственной адресации является пересылка относительных адресов (смещений). Чтобы указать, что речь идет об относительном адресе данной ячейки, а не об ее содержимом, используется описатель offset (смещение):
;Сегмент данных
mes db ‘Урок 1’ ;Строка символов
;Сегмент команд
mov DX,offset mes ;Адрес строки засылается в DX
Прямая адресация памяти
Адресуется память: адрес ячейки памяти (слова или байта) указывается в команде (обычно в символической форме) и поступает в код команды:
;Сегмент данных
mem1 dw 0 ;Слово памяти содержит 0
mem2 db 230 ;Байт памяти содержит 230
;Сегмент команд
inc mem1 ;Содержимое слова mem1 увеличивается на 1
mov DX,mem1 ;Содержимое слова с именем mem1 загружается в DX
mov AL,mem2 ;Содержимое байта с именем mem2 загружается в АL
Процессор различает группу кодов, носящих название префиксов. Имеется несколько групп префиксов: повторения, размера адреса, размера операнда, замены сегмента. Здесь нас будут интересовать префиксы замены сегмента.
Если в начале программы с помощью директивы assume указано соответствие сегменту данных сегментного регистра DS
Если в директиве assume указано соответствие сегмента данных регистру ES
До сих пор мы обсуждали адресацию ячеек, содержащихся в сегментах данных программы. Однако часто бывает нужно обратиться к памяти вне пределов программы: к векторам прерываний, системным таблицам, видеобуферу и т.д. Разумеется, такое обращение возможно только если мы знаем абсолютный адрес интересующей нас ячейки. В этом случае необходимо сначала настроить один из сегментных регистров на начало интересующей нас области, после чего можно адресоваться к ячейкам по их смещениям.
Пусть требуется вывести в левый верхний угол экрана несколько символов, например, два восклицательных знака. Эту операцию можно реализовать с помощью следующих команд:
mov AX,0B800h ;Сегментный адрес видеобуфера
mov ES,AX ;Отправим его в ES
mov byte ptr ES:0, ‘!’ ;Отправим символ на 1-е знакоместо экрана
mov byte ptr ES:2, ‘!’ ;Отправим символ на 2-е знакоместо экрана
Настроив регистр ES на сегментный адрес видеобуфера 0B800h, мы пересылаем код знака «!» сначала по относительному адресу 0 (в самое начало видеобуфера, в байт со смещением 0), а затем на следующее знакоместо, имеющее смещение 2 (в нечетных байтах видеобуфера хранятся атрибуты символов, т.е. цвет символов и фона под ними). В обеих командах необходимо с помощью обозначения ES: указать сегментный регистр, который используется для адресации памяти. Встретившись с этим обозначением, транслятор включит в код команды префикс замены сегмента, в данном случае код 26h.
В приведенном примере мы снова столкнулись с использованием атрибутивного оператора byte ptr, который позволяет в явной форме задать размер операнда. Однако если раньше этот оператор использовался, чтобы извлечь байт из данного, объявленного, как слово, то здесь его назначение иное. Транслятор, обрабатывая команду
не имеет возможности определить размер операнда-приемника. Разумеется, видеобуфер, как и любая память, состоит из байтов, однако надо ли рассматривать эту память как последовательность байтов или слов? Команда без явного задания размера операнда
Между прочим, на первый взгляд может показаться, что в обсуждаемой команде достаточно ясно указан размер правого операнда, так как символ (в данном случае «!») всегда занимает один байт. Однако транслятор, встретив обозначение «!», сразу же преобразует его в код ASCII этого символа, т.е. в число 21h, и уже не знает, откуда это число произошло и какой размер оно имеет.
Стоит еще отметить, что указание в команде описателя word ptr
При желании можно избавиться от необходимости вводить описатель размера операнда. Для этого надо пересылать не непосредственное данное, а содержимое регистра:
Здесь операндом-источником служит регистр AL, размер которого (1 байт) известен, и размер операнда-приемника определять не надо. Разумеется, команда
Для адресации к видеобуферу в вышеприведенном примере использовался сегментный регистр дополнительных данных ES. Это вполне естественно, так как обычно регистр DS служит для обращения к полям данных программы, а регистр ES как раз и предназначен для адресации всего остального. Однако при необходимости можно было воспользоваться для записи в видеобуфер регистром DS:
mov AX,0B800h ;Сегментный адрес
mov DS,AX ;видеобуфера в DS
mov byte ptr DS:0, ‘!’ ;Символ в видеобуфер
Любопытно, что хотя обозначение DS: здесь необходимо, транслятор не включит в код команды префикс замены сегмента, так как команда без префикса выполняет адресацию по умолчанию через DS.
Если, однако, по умолчанию выполняется адресация через DS, то нельзя ли опустить в последней команде обозначение сегментного регистра? Нельзя, так как обозначение «DS:число» указывает, что число является не непосредственным операндом, а адресом операнда. Команда (неправильная)
Мы рассмотрели три важнейших способа адресации: регистровую, непосредственную и прямое обращение к памяти. Все остальные режимы адресации относятся к группе косвенной адресации памяти, когда в определении адреса ячейки памяти участвует один или несколько регистров процессора. Рассмотрим последовательно эти режимы.
Косвенная адресация (базовая и индексная)
Преобразуем приведенный выше пример, чтобы продемонстрировать использование косвенной адресации через регистр.
mov AX,0B800h ;Сегментный адрес
mov ES,AX ;видеобуфера в ES
mov BX,2000 ;Смещение к середине экрана
mov byte ptr ES:[ВХ], ‘!’ ;Символ на экран
Настроив ES, мы засылаем в регистр ВХ требуемое смещение (для разнообразия к середине видеобуфера, который имеет объем точно 4000 байт), и в последней команде засылаем код в видеобуфер с помощью косвенной базовой адресации через пару регистров ES:BX с указанием замены сегмента (ES:).
Если косвенная адресация осуществляется через один из регистров ВХ, SI или DI, то подразумевается сегмент, адресуемый через DS, поэтому при адресации через этот регистр обозначение DS: можно опустить:
mov AX,0B800h ;Сегментный адрес
mov DS,AX ;видеобуфера в DS
mov BX,2000 ;Смещение к середине экрана
mov byte ptr [ВХ], ‘!’ ;Символ на экран
Кстати, этот фрагмент немного эффективнее предыдущего в смысле расходования памяти. Из-за отсутствия в коде последней команды префикса замены сегмента он занимает на 1 байт меньше места.
Регистры ВХ, SI и DI в данном применении совершенно равнозначны, и с одинаковым успехом можно воспользоваться любым из них:
mov DI,2000 ;Смещение к середине экрана
mov byte ptr [DI], ‘!’ ;Символ на экран
Не так обстоит дело с регистром ВР. Этот регистр специально предназначен для работы со стеком, и при адресации через этот регистр в режимах косвенной адресации подразумевается сегмент стека; другими словами, в качестве сегментного регистра по умолчанию используется регистр SS.
Обычно косвенная адресация к стеку используется в тех случаях, когда необходимо обратиться к данным, содержащимся в стеке, без изъятия их оттуда (например, если эти данные приходится считывать неоднократно). Пример такого рода операций будет приведен при обсуждении следующего режима адресации.
mov BX,2000 ;Смещение к середине экрана
mov byte ptr ES:[BX], ‘!’ ;Символ на экран
mov byte ptr ES:2000, ‘!’ ;Выведем символ в середину экрана
Однако команда с косвенной адресацией занимает меньше места в памяти (так как в нее не входит адрес ячейки) и выполняется быстрее команды с прямой адресацией (из-за того, что команда короче, процессору требуется меньше времени на ее считывание из памяти). Поэтому косвенная адресация эффективна в тех случаях, когда по заданному адресу приходится обращаться многократно, особенно в цикле. Выигрыш оказывается тем больше, чем большее число раз происходит обращение по указанному адресу. С другой стороны, возможности этого режима адресации невелики, и на практике чаще используют более сложные способы, которые будут рассмотрены ниже.
Косвенная адресация со смещением (базовая и индексная)
Адресуется память (байт или слово): относительный адрес операнда определяется, как сумма содержимого регистра BX, BP, SI или DI и указанной в команде константы, иногда называемой смещением. Смещение может быть числом или адресом. Так же, как и в случае косвенной адресации без смещения, при использовании регистров BX, SI и DI подразумевается сегмент, адресуемый через DS, а при использовании ВР подразумевается сегмент стека и, соответственно, регистр SS.
Рассмотрим применение косвенной адресации со смещением на примере прямого вывода в видеобуфер.
mov AX,0B800h ;Сегментный адрес
mov ES,AX ;видеобуфера в ES
mov DI,80*2*24 ;Смещение к нижней строке экрана
mov byte ptr ES:0[DI], ‘О’ ;Символ на экран
mov byte ptr ES:2[DI], ‘К’ ;Запишем символ в следующую позицию
mov byte ptr ES:4[DI], ‘!’ ;Запишем символ в следующую позицию
В этом примере для адресации выбран индексный регистр DI; в него заносится базовый относительный адрес памяти, в данном случае смещение в видеобуфере к началу последней строки экрана. Модификация этого адреса с целью получить смещение по строке экрана осуществляется с помощью констант 2 и 4, которые при вычислении процессором исполнительного адреса прибавляются к содержимому индексного регистра DI.
Иногда можно встретиться с альтернативными обозначениями того же способа адресации, которые допускает ассемблер. Вместо, например, 4[ВХ] можно с таким же успехом написать [ВХ+4], 4+[ВХ] или [ВХ]+4. Такая неоднозначность языка ничего, кроме путаницы, не приносит, однако ее надо иметь в виду, так как с этими обозначениями можно столкнуться, например, рассматривая текст дизссемблированной программы.
Рассмотрим теперь пример использования косвенной адресации со смещением при обращении к стеку:
;Основная программа
push DS ;В стек загружаются значения
push ES ;трех регистров,
push SI ;передаваемых подпрограмме mysub
call mysub ;Вызов подпрограммы mysub
;Подпрограмма mysub, принимающая три параметра в стеке
mov BP,SP ;Поместим в ВР текущий адрес вершины стека
mov АХ,2[ВР] ;Читаем в АХ последний параметр (SI)
mov ВХ,4[ВР] ;Читаем в ВХ предыдущий параметр (ES)
mov CX,6[BP] ;Читаем в СХ первый параметр (DS)
Рис. 2.15. Состояние стека после загрузки в него трех параметров и перехода на подпрограмму
Во всех приведенных выше примерах регистр использовался для хранения базового адреса, а смещение, если оно требовалось, указывалось в виде константы. Возможна и обратная ситуация, когда в качестве смещения выступает адрес массива, а в регистре находится индекс адресуемого элемента в этом массиве. Рассмотрим относительно реальный пример такого рода.
;Сегмент данных
array dw 10000 ;Резервирование 10000 слов
;Сегмент команд
mov SI,0 ;Начальное значение индекса элемента в массиве
mov АХ,0 ;Первое число-заполнитель
mov СХ,10000 ;Число шагов в цикле (всегда в СХ)
;Цикл заполнения массива значениями натуральных чисел
fill: mov array[SI],AX ;Занесение числа в элемент массива
inc AX ;Инкремент числа-заполнителя
add SI,2 ;Смещение в массиве к следующему слову
loop fill ;Переход на метку fill (CX раз)
Базово-индексная адресация
Адресуется память (байт или слово): относительный адрес операнда определяется, как сумма содержимого следующих пар регистров:
[ВХ][SI] (подразумевается DS:[BX][SI])
[ВХ][DI] (подразумевается DS:[BX][DI])
[ВР][SI] (подразумевается SS:[BP][SI])
;Сегмент данных
array dw 10000 ;Резервирование 10000 слов
;Сегмент команд
mov BX,offset array ;Адрес массива в базовом регистре BX
mov SI,0 ;Начальное значение индекса элемента в массиве
mov АХ,0 ;Первое число-заполнитель
mov СХ,10000 ;Число шагов в цикле (всегда в СХ)
;Цикл заполнения массива значениями натуральных чисел
fill: mov [BX][SI],AX ;Занесение числа в элемент массива
inc AX ;Инкремент числа-заполнителя
add SI,2 ;Смещение в массиве к следующему слову
loop fill ;Переход на метку fill (CX раз)
Повышение эффективности достигается за счет того, что команда занесения числа в элемент массива оказывается короче (так как в нее не входит адрес массива) и выполняется быстрее, так как этот адрес не надо каждый раз считывать из памяти.
Базово-индексная адресация со смещением
Адресуется память (байт или слово): относительный адрес операнда определяется как сумма содержимого двух регистров и смещения.
Это способ адресации является развитием предыдущего. В нем используются те же пары регистров, но полученный с их помощью результирующий адрес можно еще сместить на значение указанной в команде константы. Как и в случае базово-индексной адресации, константа может представлять собой индекс (и тогда в одном из регистров должен содержаться базовый адрес памяти), но может быть и базовым адресом. В последнем случае регистры могут использоваться для хранения составляющих индекса. Приведем формальный пример рассматриваемого режима адресации.
Пусть в сегменте данных определен массив из 24 байтов, в котором записаны коды латинских и русских символов верхнего ряда клавиатуры:
sym db ‘QWERTYUIOP<>‘ ;Символы английской раскладки
db ‘ЙЦУКЕНГШЩЗХЪ’ ;Символы русской раскладки
mov BX,12 ;Число байтов в строке
mov SI,6
mov DL,sym[BX][SI]
mov BX,offset sym
mov SI,6
mov DL,12[BX][SI]