Как различить в командах ассемблера прямые и косвенные режимы адресации
Перейти к содержимому

Как различить в командах ассемблера прямые и косвенные режимы адресации

Как различить в командах ассемблера прямые и косвенные режимы адресации

5.1. Способы адресации в командах языка Assembler .

Большинство команд процессора вызываются с аргументами, которые в ассемблере принято называть операндами. Например: команда сложения содержимого регистра с числом требует задания двух операндов – содержимого регистра и числа. Далее рассмотрены все существующие способы задания адреса хранения операндов – способы адресации.

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

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

Операнды могут располагаться в любых регистрах общего назначения и сегментных регистрах. Для этого в тексте программы указывается название соответствующего регистра, например: команда, копирующая в регистр АХ содержимое регистра ВХ, записывается как

5.1.2. Непосредственная адресация.

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

помещает в регистр АХ число 2.

5.1.3. Прямая адресация.

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

mov DL,meml ;Содержимое байта памяти с символическим именем meml

;пересылается в DL

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

mov AX, 0 ;Настроим сегментный регистр ES на

mov ES,AX ;самое начало памяти (адрес 0)

mov AX,ES:[0] ;АХ=содержимое слова с адресом 0000h:0000h

mov DX,ES:[2] / D Х=содержимое слова с адресом 0000h:0002h

Заметим, что в этом случае сегментный регистр надо указывать обязательно. Все остальные способы адресации относятся к группе косвенной адресации памяти.

5.1.4. Базовая и индексная адресация памяти.

Относительный адрес ячейки памяти находится в регистре, обозначение которого заключается в квадратные скобки. При использовании регистров ВХ или ВР адресацию называют базовой, при использовании регистров SI или DI — индексной. При адресации через регистры ВХ, SI или DI в качестве сегментного регистра подразумевается DS; при адресации через ВР — регистр SS. Таким образом, косвенная адресация через регистр ВР предназначена для работы со стеком. Однако при необходимости можно явно указать требуемый сегментный регистр. Еще раз отметим, что во всех базовых и индексных способах адресации операндом является содержимое ячейки памяти, адрес которой находится в том или ином регистре или вычисляется сложением содержимого двух регистров.

mov AL,[ВХ] ;Сегментный адрес предполагается в DS, смещение в ВХ

mov DL,ES:[ВХ] ;Сегментный адрес в ES, смещение в ВХ

mov DX,[ВР] ;Сегментный адрес в SS, смещение в ВР

mov AL,[DI] ;Сегментный адрес в DS, смещение в DI

5.1.5. Базовая и индексная адресации памяти со смещением.

Относительный адрес операнда определяется суммой содержимого регистра (ВХ, ВР, SI или DI) и указанного в команде числа, которое называют смещением.

mas db 1,2,5,3,7,9,8,3,4 ;Массив символов

mov BX,2 ;ВХ=индекс элемента в массиве

mov D L , mas[BX] ;В D L заносится третий элемент массива

В этом примере относительный адрес адресуемого элемента массива mas вычисляется как сумма содержимого ВХ (2) и значения символического обозначения mas, которое совпадает с относительным адресом начала массива mas. В результате в регистр D L будет загружен элемент массива mas с индексом 2, т.е. число 5. Предполагается, что базовый адрес сегмента, в который входит массив mas, загружен в DS. Такой же результат даст такая последовательность команд:

mov BX,offset mas ;ВХ=относительный адрес ячейки mas

Здесь относительный адрес адресуемого элемента массива mas вычисляется как сумма содержимого регистра ВХ и дополнительного смещения, задаваемого константой 2. Последняя команда может быть записана в следующем виде:

Адресация с помощью регистров SI и DI осуществляется аналогично. При использовании регистра ВР следует помнить, что в качестве сегментного регистра по умолчанию подразумевается регистр SS.

5.1.6. Базово-индексная адресация памяти.

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

Допускается использование следующих пар:

Если в качестве базового регистра выступает ВХ, то в качестве сегментного подразумевается DS (первые две команды); при использовании в качестве базового регистра ВР сегментным регистром по умолчанию назначается SS (вторые две команды). При необходимости можно явно указать требуемый сегментный регистр.

mov ВХ,[ВР][SI] ;В ВХ засылается слово из стека(сегментный

;адрес в SS), а смещение вычисляется как

;сумма содержимого ВР и SI

mov BX,ES:[BP][SI] ;В ВХ засылается слово из сегмента, адрес которого

;находится в ES, а смещение вычисляется как

;сумма содержимого ВР и SI

mov ES:[BX+DI],АХ ;В ячейку памяти, сегментный адрес которой

;хранится в ES, а смещение равно сумме

;содержимого ВХ и DI, пересылается содержимое АХ

5.1.7. Базово-индексная адресация памяти со смещением.

Относительный адрес операнда определяется суммой трех величин: содержимого базового и индексного регистров, а также дополнительного смещения. Допускается использование тех же пар регистров, что и в базово-индексном способе; так же действующие правила определения сегментных регистров.

mov mas[ВХ][SI],10 ;Число 10 пересылается в ячейку памяти,

;сегментный адрес которой хранится в DS, а

;смещение равно сумме содержимого

;ВХ и SI и смещения ячейки mas

mov AX,[BP+2+DI] ;В АХ пересылается из стека слово,

;смещение которого равно сумме

;ВР, DI и «добавки» 2

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

mov DL,mas[BX] ;В BХ заранее занесено число 3

mov DL,[SI][ВХ] ;В BХ заранее занесено число 3, а в SI — смещение mas

приведут к загрузке в регистр DL четвертого элемента массива mas (если выполняются описанные в комментариях условия). Однако команды с использованием различных способов адресации занимают различный объем памяти и выполняются за разное время. Так, первая из приведенных выше команд потребует для выполнения 15 машинных тактов, вторая — 18, а третья — 16. Разница невелика, однако при многократном выполнении команд в циклах суммарный эффект может быть значителен. С другой стороны, первые две команды занимают в памяти по 4 байта, а третья — только 2. Таким образом, тщательный выбор способов адресации позволяет в какой- то степени оптимизировать программы по времени выполнения или требуемой памяти, а иногда и по тому и по другому.

12. Режимы адресации

Статья основана на материале xrnd с сайта asmworld (из учебного курса по программированию на ассемблер 16-битного процессора 8086 под DOS).

Режимы адресации — это различные способы указания местоположения операндов. До этой части в учебном курсе использовались только простые режимы адресации: операнды чаще всего находились в регистрах или в переменных в памяти. Но в процессоре Intel 8086 существуют также более сложные режимы, которые позволяют организовать работу с массивами, структурами, локальными переменными и указателями. В этой части я расскажу о всех возможных режимах адресации и приведу примеры их использования.

1. Неявная адресация

Местоположение операнда фиксировано и определяется кодом операции. Примеры:

Команда CBW всегда работает с регистрами AX и AL , а у команды MUL фиксировано положение первого множителя и результата. Такой режим адресации делает машинную команду короткой, так как в ней отсутствует указание одного или нескольких операндов.

2. Непосредственная адресация

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

Обратите внимание, что в третьей строке в DX помещается адрес метки или переменной a, а вовсе не значение по этому адресу. Это особенность синтаксиса FASM. По сути адрес метки тоже является числовой константой.

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

В машинной команде содержится адрес операнда, находящегося в памяти. Пример:

Вот тут уже в DX помещается значение из памяти по адресу a . Сравните с предыдущим пунктом. Квадратные скобки обозначают обращение по адресу, указанному внутри этих скобок.

4. Относительная прямая адресация

Этот режим используется в командах передачи управления. В машинной команде содержится смещение, которое прибавляется к значению указателя команд IP . То есть указывается не сам адрес перехода, а на сколько байтов вперёд или назад надо перейти. Пример:

У такого режима адресации два преимущества. Во-первых, машинная команда становится короче, так она содержит не полный адрес, а только смещение. Во-вторых, такой код не зависит от адреса, по которому он размещается в памяти.

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

Операнд находится в регистре. Пример:

6. Косвенная регистровая (базовая) адресация

Адрес операнда находится в одном из регистров BX, SI или DI . Примеры:

Размер операнда в памяти здесь определяется размером первого операнда. Так как AX — 16-разрядный регистр, то из памяти берётся слово по адресу в BX. Так как DL — 8-разрядный регистр, то из памяти берётся байт по адресу в SI . Это правило верно и для других режимов адресации.

7. Косвенная регистровая (базовая) адресация со смещением

Адрес операнда вычисляется как сумма содержимого регистра BX, BP, SI или DI и 8- или 16-разрядного смещения. Примеры:

В качестве смещения можно указать число или адрес метки. О размере смещения не беспокойтесь — компилятор сам его определяет и использует нужный формат машинной команды.

8. Косвенная базовая индексная адресация

Адрес операнда вычисляется как сумма содержимого одного из базовых регистров BX или BP и одного из индексных регистров SI или DI . Примеры:

Например, в одном из регистров может находиться адрес начала массива в памяти, а в другом — смещение какого-то элемента относительно начала. А вообще, всё зависит от вашей фантазии ?

9. Косвенная базовая индексная адресация со смещением

Адрес операнда вычисляется как сумма содержимого одного из базовых регистров BX или BP , одного из индексных регистров SI или DI и 8- или 16-разрядного смещения. Примеры:

Пример программы

Допустим, имеется массив 32-битных целых чисел со знаком. Количество элементов массива хранится в 16-битной переменной без знака. Требуется вычислить среднее арифметическое элементов массива и сохранить его в 32-битной переменной со знаком. Я намеренно использовал разные режимы адресации, хотя тоже самое можно написать проще.

Упражнение

Объявите в программе два массива 16-битных целых со знаком. Количество элементов массивов должно быть одинаковым и храниться в 8-битной переменной без знака. Требуется из последнего элемента второго массива вычесть первый элемент первого, из предпоследнего — вычесть второй элемент и т.д. Результаты можете выкладывать в комментариях.

1. Структура машинной команды

Машинная команда представляет собой закодированное по определенным правилам указание микропроцессору на выполнение некоторой операции или действия. Каждая команда содержит элементы, определяющие:

1) что делать? (Ответ на этот вопрос дает элемент команды, называемый кодом операции (КОП).);

2) объекты, над которыми нужно что-то делать (эти элементы называются операндами);

3) как делать? (Эти элементы называются типами операндов – обычно задаются неявно).

Приведенный на рисунке 20 формат машинной команды является самым общим. Максимальная длина машинной команды – 15 байт. Реальная команда может содержать гораздо меньшее количество полей, вплоть до одного – только КОП.

Рис. 20. Формат машинной команды

Опишем назначения полей машинной команды.

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

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

а) 2eh – замена сегмента cs;

б) 36h – замена сегмента ss;

в) 3eh – замена сегмента ds;

г) 26h – замена сегмента es;

д) 64h – замена сегмента fs;

е) 65h – замена сегмента gs;

2) префикс разрядности адреса уточняет разрядность адреса (32– или 16-разрядный). Каждой команде, в которой используется адресный операнд, ставится в соответствие разрядность адреса этого операнда. Этот адрес может иметь разрядность 16 или 32 бит. Если разрядность адреса для данной команды 16 бит, это означает, что команда содержит 16-разрядное смещение (рис. 20), оно соответствует 16-разрядному смещению адресного операнда относительно начала некоторого сегмента. В контексте рисунка 21 это смещение называется эффективный адрес. Если разрядность адреса 32 бит, это означает, что команда содержит 32-разрядное смещение (рис. 20), оно соответствует 32-разрядному смещению адресного операнда относительно начала сегмента, и по его значению формируется 32-битное смещение в сегменте. С помощью префикса разрядности адреса можно изменить действующее по умолчанию значение разрядности адреса. Это изменение будет касаться только той команды, которой предшествует префикс;

Рис. 21. Механизм формирования физического адреса в реальном режиме

3) префикс разрядности операнда аналогичен префиксу разрядности адреса, но указывает на разрядность операндов (32– или 16-разрядные), с которыми работает команда. В соответствии с какими правилами устанавливаются значения атрибутов разрядности адреса и операндов по умолчанию?

В реальном режиме и режиме виртуального 18086 значения этих атрибутов – 16 бит. В защищенном режиме значения атрибутов зависят от состояния бита D в дескрипторах исполняемых сегментов. Если D = 0, то значения атрибутов, действующие по умолчанию, равны 16 бит; если D = 1, то 32 бит.

Значения префиксов разрядности операнда 66h и разрядности адреса 67h. С помощью префикса разрядности адреса в реальном режиме можно использовать 32-разрядную адресацию, но при этом необходимо помнить об ограниченности размера сегмента величиной 64 Кбайт. Аналогично префиксу разрядности адреса вы можете использовать префикс разрядности операнда в реальном режиме для работы с 32-разрядными операндами (к примеру, в арифметических командах);

4) префикс повторения используется с цепочечными командами (командами обработки строк). Этот префикс «зацикливает» команду для обработки всех элементов цепочки. Система команд поддерживает два типа префиксов:

а) безусловные (rep – OOh), заставляющие повторяться цепочечную команду некоторое количество раз;

б) условные (repe/repz – OOh, repne/repnz – 0f2h), которые при зацикливании проверяют некоторые флаги, и в результате проверки возможен досрочный выход из цикла.

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

3. Байт режима адресации modr/m.

Значения этого байта определяет используемую форму адреса операндов. Операнды могут находиться в памяти в одном или двух регистрах. Если операнд находится в памяти, то байт modr/m определяет компоненты (смещение, базовый и индексный регистры), используемые для вычисления его эффективного адреса (рисунок 21). В защищенном режиме для определения местоположения операнда в памяти может дополнительно использоваться байт sib (Scale-Index-Base – масштаб-индекс-база). Байт modr/m состоит из трех полей (рис. 20):

1) поле mod определяет количество байт, занимаемых в команде адресом операнда (рис. 20, поле смещение в команде). Поле mod используется совместно с полем r/m, которое указывает способ модификации адреса операнда «смещение в команде». К примеру, если mod = 00, это означает, что поле смещение в команде отсутствует, и адрес операнда определяется содержимым базового и (или) индексного регистра. Какие именно регистры будут использоваться для вычисления эффективного адреса, определяется значением этого байта. Если mod = 01, это означает, что поле смещение в команде присутствует, занимает 1 байт и модифицируется содержимым базового и (или) индексного регистра. Если mod = 10, это означает, что поле смещение в команде присутствует, занимает 2 или 4 байта (в зависимости от действующего по умолчанию или определяемого префиксом размера адреса) и модифицируется содержимым базового и (или) индексного регистра. Если mod =11, это означает, что операндов в памяти нет: они находятся в регистрах. Это же значение байта mod используется в случае, когда в команде применяется непосредственный операнд;

2) поле reg/коп определяет либо регистр, находящийся в команде на месте первого операнда, либо возможное расширение кода операции;

3) поле r/m используется совместно с полем mod и определяет либо регистр, находящийся в команде на месте первого операнда (если mod =11), либо используемые для вычисления эффективного адреса (совместно с полем смещение в команде) базовые и индексные регистры.

4. Байт масштаб – индекс – база (байт sib).

Используется для расширения возможностей адресации операндов. На наличие байта sib в машинной команде указывает сочетание одного из значений 01 или 10 поля mod и значения поля r/m = 100. Байт sib состоит из трех полей:

1) поля масштаба ss. В этом поле размещается масштабный множитель для индексного компонента index, занимающего следующие 3 бита байта sib. В поле ss может содержаться одно из следующих значений: 1, 2, 4, 8.

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

2) поля index. Используется для хранения номера индексного регистра, который применяется для вычисления эффективного адреса операнда;

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

5. Поле смещения в команде.

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

6. Поле непосредственного операнда.

Необязательное поле, представляющее собой 8-, 16– или 32-разрядный непосредственный операнд. Наличие этого поля, конечно, отражается на значении байта modr/m.

2. Способы задания операндов команды

В этом случае команда явно не содержит операндов. Алгоритм выполнения команды использует некоторые объекты по умолчанию (регистры, флаги в eflags и т. д.).

Например, команды cli и sti неявно работают с флагом прерывания if в регистре eflags, а команда xlat неявно обращается к регистру al и строке в памяти по адресу, определяемому парой регистров ds: bx.

Операнд задается в самой команде (непосредственный операнд)

Операнд находится в коде команды, т. е. является ее частью. Для хранения такого операнда в команде выделяется поле длиной до 32 бит (рисунок 20). Непосредственный операнд может быть только вторым операндом (источником). Операнд-получатель может находиться либо в памяти, либо в регистре.

Например: mov ax,0ffffti пересылает в регистр ах шестнадцатеричную константу ffff. Команда add sum, 2 складывает содержимое поля по адресу sum с целым числом 2 и записывает результат по месту первого операнда, т. е. в память.

Операнд находится в одном из регистров

Регистровые операнды указываются именами регистров. В качестве регистров могут использоваться:

1) 32-разрядные регистры ЕАХ, ЕВХ, ЕСХ, EDX, ESI, EDI, ESP, ЕВР;

2) 16-разрядные регистры АХ, BX, СХ, DX, SI, DI, SP, ВР;

3) 8-разрядные регистры АН, AL, ВН, BL, СН, CL, DH, DL;

4) сегментные регистры CS, DS, SS, ES, FS, GS.

Например, команда add ax,bx складывает содержимое регистров ах и bх и записывает результат в bх. Команда dec si уменьшает содержимое si на 1.

Операнд располагается в памяти

Это наиболее сложный и в то же время наиболее гибкий способ задания операндов. Он позволяет реализовать следующие два основных вида адресации: прямую и косвенную.

В свою очередь, косвенная адресация имеет следующие разновидности:

1) косвенную базовую адресацию; другое ее название – регистровая косвенная адресация;

2) косвенную базовую адресацию со смещением;

3) косвенную индексную адресацию со смещением;

4) косвенную базовую индексную адресацию;

5) косвенную базовую индексную адресацию со смещением.

Операндом является порт ввода/вывода

Помимо адресного пространства оперативной памяти, микропроцессор поддерживает адресное пространство ввода-вывода, которое используется для доступа к устройствам ввода-вывода. Объем адресного пространства ввода-вывода составляет 64 Кбайт. Для любого устройства компьютера в этом пространстве выделяются адреса. Конкретное значение адреса в пределах этого пространства называется портом ввода-вывода. Физически порту ввода-вывода соответствует аппаратный регистр (не путать с регистром микропроцессора), доступ к которому осуществляется с помощью специальных команд ассемблера in и out.

in al,60h; ввести байт из порта 60h

Регистры, адресуемые с помощью порта ввода-вывода, могут иметь разрядность 8,16 или 32 бит, но для конкретного порта разрядность регистра фиксирована. Команды in и out работают с фиксированной номенклатурой объектов. В качестве источника информации или получателя применяются так называемые регистры-аккумуляторы ЕАХ, АХ, AL. Выбор регистра определяется разрядностью порта. Номер порта может задаваться непосредственным операндом в командах in и out или значением в регистре DX. Последний способ позволяет динамически определить номер порта в программе.

Операнд находится в стеке

Команды могут совсем не иметь операндов, иметь один или два операнда. Большинство команд требуют двух операндов, один из которых является операндом-источником, а второй – операндом назначения. Важно то, что один операнд может располагаться в регистре или памяти, а второй операнд обязательно должен находиться в регистре или непосредственно в команде. Непосредственный операнд может быть только операндом-источником. В двухоперандной машинной команде возможны следующие сочетания операндов:

1) регистр – регистр;

2) регистр – память;

3) память – регистр;

4) непосредственный операнд – регистр;

5) непосредственный операнд – память.

У данного правила есть исключения, которые касаются:

1) команд работы с цепочками, которые могут перемещать данные из памяти в память;

2) команд работы со стеком, которые могут переносить данные из памяти в стек, также находящийся в памяти;

3) команд типа умножения, которые, кроме операнда, указанного в команде, используют еще и второй, неявный операнд.

Из перечисленных сочетаний операндов наиболее часто употребляются регистр – память и память – регистр. Ввиду их важности рассмотрим их подробнее. Обсуждение мы будем сопровождать примерами команд ассемблера, которые будут показывать, как изменяется формат команды ассемблера при применении того или иного вида адресации. В связи с этим посмотрите еще раз на рисунке 21, на котором показан принцип формирования физического адреса на адресной шине микропроцессора. Видно, что адрес операнда формируется как сумма двух составляющих – сдвинутого на 4 бита содержимого сегментного регистра и 16-битного эффективного адреса, который в общем случае вычисляется как сумма трех компонентов: базы, смещения и индекса.

3. Способы адресации

Перечислим и затем рассмотрим особенности основных видов адресации операндов в памяти:

1) прямую адресацию;

2) косвенную базовую (регистровую) адресацию;

3) косвенную базовую (регистровую) адресацию со смещением;

4) косвенную индексную адресацию со смещением;

5) косвенную базовую индексную адресацию;

6) косвенную базовую индексную адресацию со смещением.

Прямая адресация

Это простейший вид адресации операнда в памяти, так как эффективный адрес содержится в самой команде и для его формирования не используется никаких дополнительных источников или регистров. Эффективный адрес берется непосредственно из поля смещения машинной команды (см. рис. 20), которое может иметь размер 8, 16, 32 бит. Это значение однозначно определяет байт, слово или двойное слово, расположенные в сегменте данных.

Прямая адресация может быть двух типов.

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

Используется для команд условных переходов, для указания относительного адреса перехода. Относительность такого перехода заключается в том, что в поле смещения машинной команды содержится 8-, 16– или 32-битное значение, которое в результате работы команды будет складываться с содержимым регистра указателя команд ip/eip. В результате такого сложения получается адрес, по которому и осуществляется переход.

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

В этом случае эффективный адрес является частью машинной команды, но формируется этот адрес только из значения поля смещения в команде. Для формирования физического адреса операнда в памяти микропроцессор складывает это поле со сдвинутым на 4 бита значением сегментного регистра. В команде ассемблера можно использовать несколько форм такой адресации.

Но такая адресация применяется редко – обычно используемым ячейкам в программе присваиваются символические имена. В процессе трансляции ассемблер вычисляет и подставляет значения смещений этих имен в формируемую им машинную команду в поле «смещение в команде». В итоге получается так, что машинная команда прямо адресует свой операнд, имея, фактически, в одном из своих полей значение эффективного адреса.

Остальные виды адресации относятся к косвенным. Слово «косвенный» в названии этих видов адресации означает то, что в самой команде может находиться лишь часть эффективного адреса, а остальные его компоненты находятся в регистрах, на которые указывают своим содержимым байт modr/m и, возможно, байт sib.

Косвенная базовая (регистровая) адресация

При такой адресации эффективный адрес операнда может находиться в любом из регистров общего назначения, кроме sp/esp и bp/ebp (это специфические регистры для работы с сегментом стека). Синтаксически в команде этот режим адресации выражается заключением имени регистра в квадратные скобки []. К примеру, команда mov ах, [есх] помещает в регистр ах содержимое слова по адресу из сегмента данных со смещением, хранящимся в регистре есх. Так как содержимое регистра легко изменить в ходе работы программы, данный способ адресации позволяет динамически назначить адрес операнда для некоторой машинной команды. Это свойство очень полезно, например, для организации циклических вычислений и для работы с различными структурами данных типа таблиц или массивов.

Косвенная базовая (регистровая) адресация со смещением

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

К примеру, команда mov ax,[edx+3h] пересылает в регистр ах слова из области памяти по адресу: содержимое edx + 3h.

Команда mov ax,mas[dx] пересылает в регистр ах слово по адресу: содержимое dx плюс значение идентификатора mas (не забывайте, что транслятор присваивает каждому идентификатору значение, равное смещению этого идентификатора относительно начала сегмента данных).

Косвенная индексная адресация со смещением

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

Посмотрите на рисунок 20. Нас интересует байт sib. При обсуждении структуры этого байта мы отмечали, что он состоит из трех полей. Одно из этих полей – поле масштаба ss, на значение которого умножается содержимое индексного регистра.

К примеру, в команде mov ax,mas[si*2] значение эффективного адреса второго операнда вычисляется выражением mas+(si)*2. В связи с тем, что в ассемблере нет средств для организации индексации массивов, то программисту своими силами приходится ее организовывать.

Наличие возможности масштабирования существенно помогает в решении этой проблемы, но при условии, что размер элементов массива составляет 1, 2, 4 или 8 байт.

Косвенная базовая индексная адресация

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

Косвенная базовая индексная адресация со смещением

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

К примеру, команда mov eax,[esi+5] [edx] пересылает в регистр еах двойное слово по адресу: (esi) + 5 + (edx).

Команда add ax,array[esi] [ebx] производит сложение содержимого регистра ах с содержимым слова по адресу: значение идентификатора array + (esi) + (ebx).

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *