Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Ассемблеры. Режимы адресации.



— Ассемблер - компьютерная программа, компилятор исходного текста программы, написанной на языке ассемблера, в программу на машинном языке.

— Ассемблер обрабатывает программу, команды которой отображают внутреннюю структуру процессора и памяти.

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

Различают следующие режимы адресации:

§ регистровый;

Значение операнда-источника предварительно запоминается в одном из встроенных регистров микропроцессора. Сам регистр становится эффективным адресом. Операнд (байт или слово) находится в регистре. Этот способ применим ко всем программно-адрессуемым регистрам процессора (напр-р, inc CX, mov ES, AX)

§ непосредственный;

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

(напр-р, mov AH,40h; int 21h, mov CX,limit – число, обозначенное limit, загруж-ся в CX)

Команда mov, использованная в последнем предложении, имеет два операнда; первый операнд определяется с помощью регистровой адресации, второй – с помощью непосредственной.

§ прямой;

Адресуется память; адрес ячейки памяти (слова или байта) указывается в команде (обычно в символической форме) и поступает в код команды:

;Сегмент данных

meml dw 0 ;Слово памяти содержит 0

mem2 db 230 ;Байт памяти содержит 230

;Сегмент команд

inc meml ;Содержимое слова meml увеличивается на 1

mov DX, meml ;Содержимое слова с именем menu загружается в DX

mov AL,mem2 ;Содержимое байта с именем mem2 загружается в АL

Сравнивая этот пример с предыдущим, мы видим, что указание в команде имени ячейки памяти обозначает, что операндом является содержимое этой ячейки; указание имени ячейки с описателем offset – что операндом является адрес ячейки.

Прямая адресация памяти на первой взгляд, кажется, простой и наглядной. Если мы хотим обратиться, например, к ячейке meml, мы просто указываем ее имя в программе. В действительности, однако, дело обстоит сложнее. Адрес любой ячейки состоит из двух компонентов: сегментного адреса и смещения. Обозначения meml и mem2 в предыдущем примере, являются смещениями. Сегментные же адреса хранятся в сегментных регистрах. Однако сегментных регистров четыре: DS, ES, CS и SS. Каким образом процессор узнает, из какого регистра взять сегментный адрес, и как сообщить ему об этом в программе?

ПР различает группу кодов, носящих название префиксов. Имеется несколько групп префиксов: повторения, размера адреса, размера операнда, замены сегмента. Здесь нас будут интересовать префиксы замены сегмента.

Команды процессора, обращающиеся к памяти, могут в качестве первого байта своего кода содержать префикс замены сегмента, с помощью которого процессор определяет, из какого сегментного регистра взять сегментный адрес. Для сегментного регистра ES код префикса составляет 26h, для SS – 361i, для CS – 2Eh. Если префикс отсутствует, сегментный адрес берется из регистра DS (хотя для него тоже предусмотрен свой префикс).

В приведенном примере, по умолчанию, все данные адресуются через сегментный регистр DS, так что вместо inc meml можно было написать inc DS:mem. В случае замены сегментного регистра его обязательно нужно указывать явно:

inc ES:mem1

inc CS:mem2

Обращение к ЯП по известному абсолютному адресу осуществляется следующим образом:

mov AL,DS:[17h] - Загрузка в AL содержимого ячейки со смещением 17h в сегменте, определяемом содержимым DS

§ регистровый косвенный (базовый или индексный);

Адресуется память (байт или слово). Относительный адрес ячейки памяти находится в регистре, обозначение которого заключается в прямые скобки. В МП 86 косвенная адресация допустима только через регистры ВХ, ВР, SI и DI. При использовании регистров ВХ или ВР адресацию называют базовой, при использовании регистров SI или DI – индексной.

Если косвенная адресация осуществляется через один из регистров ВХ, SI или DI, то подразумевается сегмент, адресуемый через DS, поэтому при адресации через этот регистр обозначение DS: можно опустить:

mov es:[bx],’1′ ――――→ mov [bx],’1′

Кстати, этот фрагмент немного эффективнее предыдущего в смысле расходования памяти. Из-за отсутствия в коде последней команды префикса замены сегмента он занимает на 1 байт меньше места.

Регистры ВХ, SI и DI в данном применении совершенно равнозначны, и с одинаковым успехом можно воспользоваться любым из них:

Не так обстоит дело с регистром ВР. Этот регистр специально предназначен для работы со стеком, и при адресации через этот регистр в режимах косвенной адресации подразумевается сегмент стека; другими словами, в качестве сегментного регистра по умолчанию используется регистр SS.

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

Обозначение этого способа адресации:

[BX] (подразумевается DS:[BX])

[BP] (подразумевается SS:[BP])

[SI] (подразумевается DS:[SI])

[DI] (подразумевается DS:[DI])

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

Примеры:

1. mov SI, offset string; В SI загружается относительный адрес ячейки string

2. mov AX,[SI] ; Содержимое ячейки string загружается в AX

3. inc [SI] ; Увеличиваться содержимое ячейки string

4. mov BX,[SI] ; Новое содержимое ячейки string загружается в B

5. mov DI, SI ; Относительный адрес ячейки string копируется в DI

§ регистровый косвенный со смещением (базовый или индексный);

Адресуется память (байт или слово). Относительный адрес операнда определяется, как сумма содержимого регистра BX, BP, SI или DI и указанной в команде константы, иногда называемой смещением. Смещение может быть числом или адресом. Так же, как и в случае базовой адресации, при использовании регистров BX, SI и DI подразумевается сегмент, адресуемый через DS, а при использовании ВР подразумевается сегмент стека и, соответственно, регистр SS.

смещение = {SP, BP, DI, SI, BX} + смещение из команды. Иногда можно встретиться с альтернативными обозначениями того же способа адресации, которые допускает ассемблер. Вместо, например, 4[ВХ] можно с таким же успехом написать [ВХ+4], 4+[ВХ] или [ВХ]+4. Такая неоднозначность языка ничего, кроме путаницы, не приносит, однако ее надо иметь в виду, так как с этими обозначениями можно столкнуться, например, рассматривая текст деассемблированной программы.

Рассмотрим теперь пример использования базовой адресации со смещением при обращении к стеку:

смещение = {SP, BP, DI, SI, BX} + смещение из команды

Здесь квадратные скобки [ ] – это тоже оператор. Он вычисляет адрес как сумму того, что находится внутри скобок с тем, что находится снаружи.

array db 0, 10, 20, 30, 40, 50, 60 ;Пусть в сегменте данных определен массив:

Последовательность команд:

mov BX,5

mov AL,array[5] ;загрузит в AL элемент массива с индексом 5, то есть 50.

Тот же результат будет получен и в таких последовательностях команд:

mov BX,offset array

mov AL,5[BX]

или

mov AL,[BX]+5

mov AL,[BX+5]

§ базово-индексный;

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

смещение [BX][SI] (подразумевается DS:смещение [BX][SI])

смещение [BX][DI] (подразумевается DS:смещение [BX][DI])

смещение [BP][SI] (подразумевается SS:смещение [BP][SI])

смещение [BP][DI] (подразумевается SS:смещение [BP][DI])

Во всех этих случаях можно также писать:

смещение [BX+SI]

[смещение +BX+SI]

[BX+SI]+смещение

Это чрезвычайно распространенный способ адресации, особенно, при работе с массивами. В нем используются два регистра, при этом одним из них должен быть базовый (ВХ или ВР), а другим – индексный (SI или DI). Как правило, в одном из регистров находится адрес массива, а в другом – индекс в нем, при этом совершенно безразлично, в каком что.


Поделиться:



Последнее изменение этой страницы: 2019-05-08; Просмотров: 216; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.019 с.)
Главная | Случайная страница | Обратная связь