Практическое занятие № 20
Изучение режимов адресации
Режимы адресации — это различные способы указания местоположения операндов. До этой части в учебном курсе использовались только простые режимы адресации: операнды чаще всего находились в регистрах или в переменных в памяти. Но в процессоре Intel 8086 существуют также более сложные режимы, которые позволяют организовать работу с массивами, структурами, локальными переменными и указателями. В этой части я расскажу о всех возможных режимах адресации и приведу примеры их использования.
1. Неявная адресация
Местоположение операнда фиксировано и определяется кодом операции. Примеры:
|
cbw mul al |
Команда CBW всегда работает с регистрами AX и AL, а у команды MUL фиксировано положение первого множителя и результата. Такой режим адресации делает машинную команду короткой, так как в ней отсутствует указание одного или нескольких операндов.
2. Непосредственная адресация
При непосредственной адресации значение операнда является частью машинной команды. Понятно, что в этом случае операнд представляет собой константу. Примеры:
|
mov al,5 add bx,1234h mov dx,a |
Обратите внимание, что в третьей строке в DX помещается адрес метки или переменной a, а вовсе не значение по этому адресу. Это особенность синтаксиса FASM. По сути адрес метки тоже является числовой константой.
3. Абсолютная прямая адресация
В машинной команде содержится адрес операнда, находящегося в памяти. Пример:
|
mov dx,[a] |
Вот тут уже в DX помещается значение из памяти по адресу a. Сравните с предыдущим пунктом. Квадратные скобки обозначают обращение по адресу, указанному внутри этих скобок.
4. Относительная прямая адресация
Этот режим используется в командах передачи управления. В машинной команде содержится смещение, которое прибавляется к значению указателя команд IP. То есть указывается не сам адрес перехода, а на сколько байтов вперёд или назад надо перейти. Пример:
|
metka: ... loop metka |
У такого режима адресации два преимущества. Во-первых, машинная команда становится короче, так она содержит не полный адрес, а только смещение. Во-вторых, такой код не зависит от адреса, по которому он размещается в памяти.
5. Регистровая адресация
Операнд находится в регистре. Пример:
|
add ax,bx |
|
|
6. Косвенная регистровая (базовая) адресация
Адрес операнда находится в одном из регистров BX, SI или DI. Примеры:
|
add ax,[bx] mov dl,[si] |
Размер операнда в памяти здесь определяется размером первого операнда. Так как AX — 16-разрядный регистр, то из памяти берётся слово по адресу в BX. Так как DL — 8-разрядный регистр, то из памяти берётся байт по адресу в SI. Это правило верно и для других режимов адресации.
7. Косвенная регистровая (базовая) адресация со смещением
Адрес операнда вычисляется как сумма содержимого регистра BX, BP, SI или DI и 8- или 16-разрядного смещения. Примеры:
|
add ax,[bx+2] mov dx,[array1+si] |
В качестве смещения можно указать число или адрес метки. О размере смещения не беспокойтесь — компилятор сам его определяет и использует нужный формат машинной команды.
8. Косвенная базовая индексная адресация
Адрес операнда вычисляется как сумма содержимого одного из базовых регистров BX или BP и одного из индексных регистров SI или DI. Примеры:
|
mov ax,[bp+si] add ax,[bx+di] |
Например, в одном из регистров может находиться адрес начала массива в памяти, а в другом — смещение какого-то элемента относительно начала.
9. Косвенная базовая индексная адресация со смещением
Адрес операнда вычисляется как сумма содержимого одного из базовых регистров BX или BP, одного из индексных регистров SI или DI и 8- или 16-разрядного смещения. Примеры:
|
mov al,[bp+di+5] mov bl,[array2+bx+si] |
Пример программы
Допустим, имеется массив 32-битных целых чисел со знаком. Количество элементов массива хранится в 16-битной переменной без знака. Требуется вычислить среднее арифметическое элементов массива и сохранить его в 32-битной переменной со знаком.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
use16 ;Генерировать 16-битный код org 100h ;Программа начинается с адреса 100h
sub ax,ax ;AX = 0 cwd ;DX = 0 mov si,ax ;SI = 0 - смещение элемента от начала массива mov bx,array ;Помещаем в BX адрес начала массива mov di,n ;Помещаем в DI адрес n mov cx,[di] ;CX = n lp1: add ax,[bx+si] ;Прибавление младшего слова adc dx,[bx+si+2] ;Прибавление старшего слова add si,4 ;Увеличиваем смещение в SI на 4 loop lp1 ;Команда цикла
idiv word[di] ;Делим сумму на количество элемнтов cwd ;DX:AX = AX mov word[m],ax ;\ Сохраняем mov word[m+2],dx ;/ результат
mov ax,4C00h ;\ int 21h ;/ Завершение программы ;------------------------------------------------------- n dw 10 array dd 10500,-7500,-15000,10000,-8000 dd 6500,11500,-5000,10500,-20000 m dd ? |
Задание
Объявите в программе два массива 16-битных целых со знаком. Количество элементов массивов должно быть одинаковым и храниться в 8-битной переменной без знака. Требуется из последнего элемента второго массива вычесть первый элемент первого, из предпоследнего — вычесть второй элемент и т.д.
Материалы на данной страницы взяты из открытых источников либо размещены пользователем в соответствии с договором-офертой сайта. Вы можете сообщить о нарушении.