- •354000 «Прикладная информатика»
- •Idiv Деление целых знаковых чисел
- •Imul Умножение целых знаковых чисел
- •In Ввод из порта
- •Inc Инкремент (увеличение на 1)
- •Int Программное прерывание
- •I into Прерывание по переполнению
- •Iret Возврат из программы обработки прерывания
- •Xchg Обмен данными между операндами
- •Xlat Табличная трансляция
- •Xor Логическое исключающее или
- •Загрузка и выполнение программ
- •Составление программы на языке Assembler и её размещение в памяти компьютера. Стандартное распределение памяти под программные сегменты.
- •Оператор Текст
- •Имя Операнд_1 ;
- •Имя Операнд_1
- •Загрузка и выполнение программ
- •Mov dl,10 ;Позиция X
- •In Считать данные из порта.
- •Исследование команд, выполняемых процессором. Программирование операций с помощью отладчика языка Assembler..
- •Исследование операций с памятью компьютера. Программирование на языка Assembler в операционной системе ms-dos. Обычная память
- •Косвенная адресация
- •Адресация по базе со сдвигом
- •Косвенная адресация с масштабированием
- •Адресация по базе с индексированием
- •Программирование прерываний на языке Assembler в операционной системе ms-dos.
- •Исследование механизмов работа с видеопамятью персонального компьютера типа ibm. Тестирование и отладка ассемблерных программ.
Косвенная адресация
По аналогии с регистровыми и непосредственными операндами адрес операнда в памяти также можно не указывать, а хранить в любом регистре. До процессора 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