Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2012 ЛР Ассемблер Архитектура ВС 6 семестр.doc
Скачиваний:
7
Добавлен:
03.05.2019
Размер:
454.66 Кб
Скачать

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

По аналогии с регистровыми и непосредственными операндами адрес операн­да в памяти также можно не указывать, а хранить в любом регистре. До процессо­ра 80386 для этого можно было использовать только ВХ, SI, DI и ВР, но потом ограничения были сняты и адрес операнда разрешили считывать также из ЕАХ, ЕВХ, ЕСХ, EDX, ESI, EDI, ЕВР и ESP (но не из АХ, СХ, DX или SP напрямую -надо использовать ЕАХ, ЕСХ, EDX, ESP соответственно или предварительно ско­пировать смещение в ВХ, SI, DI или ВР). Например, следующая команда помещает в регистр AX слово из ячейки памяти, селектор сегмента которой находится в DS, а смещение - в ВХ:

mov ax,[bx]

Как и в случае с прямой адресацией, DS используется по умолчанию, но не всегда: если смещение берут из регистров ESP, ЕВР или ВР, то в качестве сегмен­тного регистра применяется SS. В реальном режиме можно свободно работать со всеми 32-битными регистрами, надо только следить, чтобы их содержимое не пре­вышало границ 16-битного слова.

Адресация по базе со сдвигом

Теперь скомбинируем два предыдущих метода адресации. Следующая команда

mov ах,[Ьх+2]

помещает в регистр АХ слово, которое есть в сегменте, указанном в DS, со смеще­нием на два больше, чем число из ВХ. Так как слово занимает ровно 2 байта, эта команда поместила в АХ слово, непосредственно следующее за тем, которое было в предыдущем примере. Такая форма адресации используется в тех случаях, ког­да в регистре находится адрес начала структуры данных, а доступ надо осуще­ствить к какому-нибудь ее элементу. Еще один вариант применения адресации по базе со сдвигом - доступ из подпрограммы к параметрам, переданным в стеке, ис­пользуя регистр ВР (ЕВР) в качестве базы и номер параметра в качестве смеще­ния. Другие допустимые формы записи этого способа адресации:

mov ax,[bp]+2

mov ax,2[bp]

До процессора 80386 в качестве базового регистра разрешалось использовать только ВХ, ВР, SI или DI и сдвиг мог быть только байтом или словом (со знаком). Начиная с 80386 и старше, процессоры Intel позволяют дополнительно использо­вать ЕАХ, ЕВХ, ЕСХ, EDX, ЕВР, ESP, ESI и EDI, так же как и для обычной косвен­ной адресации. С помощью этого метода разрешается организовывать доступ к од­номерным массивам байтов: смещение соответствует адресу начала массива, а число в регистре - индексу элемента массива, который надо считать. Очевидно, что, если массив состоит не из байтов, а из слов, придется умножать базовый ре­гистр на два, а если из двойных слов - на четыре. Для этого предусмотрен специ­альный метод - косвенная адресация.

Косвенная адресация с масштабированием

Этот метод адресации полностью идентичен предыдущему, однако с его помо­щью можно прочитать элемент массива слов, двойных слов или учетверенных слов, просто поместив номер элемента в регистр:

mov ax,[esi*2]+2

Множитель, который равен 1, 2, 4 или 8, соответствует размеру элемента мас­сива - байту, слову, двойному или учетверенному слову. Из регистров в этом варианте адресации можно использовать только ЕАХ, ЕВХ, ЕСХ, EDX, ESI, EDI, ЕВР, ESP, но не SI, DI, ВР или SP.

Адресация по базе с индексированием

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

mov ax,[bx+si+2]

mov ax,[bx][si]+2

mov ax,[bx+2][si]

mov ax,[bx][si+2]

mov ax,2[bx][si]

В регистр АХ помещается слово из ячейки памяти со смещением, равным сум­ме чисел, содержащихся в ВХ, SI, и числа 2. Из 16-битных регистров так можно складывать только ВХ + SI, ВХ + DI, ВР + SI и ВР + DI, а из 32-битных - все восемь регистров общего назначения. Как и для прямой адресации, вместо непос­редственного указания числа разрешено использовать имя переменной, заданной одной из директив определения данных. Таким образом можно считать, напри­мер, число из двумерного массива: если задана таблица 10х10 байт, 2 - смещение ее начала от начала сегмента данных (на практике будет использоваться имя этой таблицы), ВХ = 20, а SI = 7, приведенные команды прочитают слово, состоящее из седьмого и восьмого байтов третьей строки. Если таблица состоит не из оди­ночных байтов, а из слов или двойных слов, удобнее использовать наиболее пол­ную форму - адресацию по базе с индексированием и масштабированием.

Пример программы записи в EMS –память результата сложения двух чисел.

.model tiny

.code

org 100h

.286

start:

mov dx,offset mess

mov ah,9

int 21h

;проверка наличия устройства emmxxxx0

mov dx,offset ems_driver

mov ax,3d00h

int 21h

jc no_emmx ;нет устройства

mov bx,ax

mov ax,4400h

int 21h

jc no_ems ;не открывается

test dx,80h

jz no_ems ;оно файл

;выделить память под буфер в ems

mov ax,4100h ;получить адрес окна

int 67h

mov bp,bx

mov ax,4300h

mov bx,1

int 67h ;выделить 1*16 кб

cmp ah,0

jnz ems_failed ;не хватает памяти

mov word ptr ems_handle,dx ;сохраним информацию

mov ax,4400h

mov bx,0

int 67h ;отобразить в страницу 0

mov ah,9

mov dx, offset ems_msg1

int 21h ;оно есть

mov ax,bp ;адрес окна в ax

jmp short ems_used

ems_failed:

no_ems:

mov ah,3eh

int 21h ;закроем файл устройство

no_emmx:

mov ah,9 ;не получилось

mov dx,offset conv_msg

int 21h

jmp exit

;используем

ems_used:

mov word ptr buffer_seg,ax ;Сохраняем сегментный адрес буфера ЕММ

mov es,ax ;Запись в ES-сегментный регистр ;сегментный адрес буфера ЕММ

mov al,50h

mov ah,12h

add al,ah ;складываем источник с приемником

mov es:0,ax

mov ax,4700h ;сохраним

int 67h

mov ax,es:0

mov dh,al

and dh,0fh ;логическое И,в DH-младшие 4 бита

shr al, 4 ;в AL-старшие

call m2 ;вывести старшую цифру

mov al,dh ; в AL-младшие 4 бита

m2: cmp al,10 ;Три команды, переводящие в AL

sbb al,69h ;в соответствующий ASCII-код

das

mov dl,al ;в DL помещаем код символа

mov ah,2 ;номер в AH

int 21h

exit: ret

ems_driver db "EMSXXXX0",0 ;название устройства

conv_msg db"не хватает EMS памяти"

ems_msg db 'EMS в памяти не обнаружен',0dh,0ah,'$'

ems_msg1 db 'EMS в памяти ЕСТЬ',0dh,0ah,'$'

ems_handle dw 0 ;индификатор ЕМS

buffer_seg dw 0 ;сегментный адрес ЕМS

mess db "Emm",0dh,0ah

db " Работа с emm",0dh,0ah,'$'

chislo db "0000"

end start

Задание:

Записать результат лабораторной работы №2 в EMS – память.

Лабораторная работа №4

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]