Способы адресации
Во всех приведенных выше примерах регистр использовался для хранения базового адреса, а смещение, если оно требовалось, указывалось в виде константы. Возможна и обратная ситуация, когда в качестве смещения выступает адрес массива, а в регистре находится индекс адресуемого элемента в этом массиве. Рассмотрим относительно реальный пример такого рода.
Пусть нам надо заполнить массив из 10000 слов натуральным рядом чисел. Зарезервируем в сегменте данных место под этот массив, а в сегменте команд организуем цикл занесения в последовательные слова массива ряда нарастающих чисел. Нам придется воспользоваться несколькими новым командами (inc, add и loop), которые в дальнейшем будут рассмотрены более подробно.
;Сегмент данных array dw 10000 ;Сегмент команд mov SI, 0;Начальное значение индекса элемента в массиве mov АХ, 0;Первое число-заполнитель mov СХ,10000;Число шагов в цикле (всегда в СХ) fill: mov array[SI],AX;Занесение числа в элемент массива inc AX;Инкремент числа-заполнителя add SI,2;Смещение в массиве к следующему слову loop fill;Возврат на метку fill (СХ раз)
Цикл начинается с команды, помеченной меткой fill (правила образования имен меток такие же, как и для имен полей данных). В этой команде содержимое АХ, поначалу равное 0, переносится в ячейку памяти, адрес которой вычисляется, как сумма адреса массива array и содержимого индексного регистра SI, в котором в первом шаге никла тоже 0. В результате в первое слово массива заносится 0. Далее содержимое регистра АХ увеличивается на 1, содержимое регистра SI – на 2 (из-за того, что массив состоит из слов), и командой loop осуществляется переход на метку fill, после чего тело цикла повторяется при новых значениях регистров АХ и SI. Число шагов в цикле, отсчитываемое командой loop, определяется исходным содержимым регистра СХ.
Базово-индексная адресация
Адресуется память (байт или слово). Относительный адрес операнда определяется, как сумма содержимого следующих пар регистров:
[ВХ] [SI] (подразумевается DS:[BX][SI]) [ВХ][DI] (подразумевается DS:[BX][DI]) [ВР] [SI] (подразумевается SS:[BP][SI]) [ВР] [DI] (подразумевается SS:[BP][DI])
Это чрезвычайно распространенный способ адресации, особенно, при работе с массивами. В нем используются два регистра, при этом одним из них должен быть базовый (ВХ или ВР), а другим – индексный (SI или DI). Как правило, в одном из регистров находится адрес массива, а в другом – индекс в нем, при этом совершенно безразлично, в каком что. Трансформируем предыдущий пример, введя в него более эффективную базово-индексную адресацию.
;Сегмент данных array dw 10000 ;Сегмент команд mov BX,offset array;Базовый адрес массива в ;базовом регистре mov SI, 0;Начальное значение индекса ;элемента в массиве mov АХ, 0;Первое число-заполнитель mov CX,10000;Число шагов в цикле fill: mov [BX][SI],AX;Отправим число в массив inc AX;Инкремент числа-заполнителя add SI, 2;Смещение в массиве к следующему слову loop fill;На метку fill (CX раз)
Повышение эффективности достигается за счет того, что команда занесения числа в элемент массива оказывается короче (так как в нее не входит адрес массива) и выполняется быстрее, так как этот адрес не надо каждый раз считывать из памяти.
Базово-индексная адресация со смещением
Адресуется память (байт или слово). Относительный адрес операнда определяется как сумма содержимого двух регистров и смещения.
Это способ адресации является развитием предыдущего. В нем используются те же пары регистров, но полученный с их помощью результирующий адрес можно еще сместить на значение указанной в команде константы. Как и в случае базово-индексной адресации, константа может представлять собой индекс (и тогда в одном из регистров должен содержаться базовый адрес памяти), но может быть и базовым адресом. В последнем случае регистры могут использоваться для хранения составляющих индекса. Приведем формальный пример рассматриваемого режима адресации.
Пусть в сегменте данных определен массив из 24 байтов, в котором записаны коды латинских и русских символов верхнего ряда клавиатуры:
sims db "QWERTYUIOP{}' db "ЙЦУКЕНПШЦЗХЪ'
Последовательность команд:
mov BX,12;Число байтов в строке mov SI, 6 mov DL,syms[BX][SI]
Загрузит в регистр DL элемент с индексом 6 из второго ряда, т.е. код ASCII буквы Г. Тот же результат можно получить, загрузив в один из регистров не индекс, а адрес массива:
mov BX, off set sym mov SI,6 mov DL, 12 [BX] [SI]