- •Практическая работа № 7.
- •2) Lds и les (Load ds и Load es) — команды загрузки адреса, состоящего из двух слов, в пару регистров (сегментный регистр и, чаще всего, базовый).
- •2) Loope (loopz) — выполнять цикл пока нуль, выход по «не нулю».
- •3) Loopne (loopnz) — выполнять цикл пока не 0, выход по «нулю»
- •Пример программы Таблица 3.5
- •Контрольные вопросы
- •Практические задания
Практическая работа № 7.
ТЕМА: "Система команд CPU i8086. Команда загрузки исполнительного адреса. Команды, организующие циклы".
ЦЕЛЬ:
Изучить особенности выполнения команд, организующих циклы (LOOPx), и команды загрузки исполнительного адреса (LEA) из системы команд процессора.
Научиться использовать указанные команды при составлении программ циклической структуры на языке ассемблера. Закрепить назначение регистра счетчика CX.
Закрепить умения по кодированию и декодированию команд, организующих циклы, и команды LEA.
Ход работы.
Познакомиться с необходимой теоретической информацией.
Ответить на контрольные вопросы.
Выполнить предложенные задания.
Оформить отчет.
Защитить работу.
Повторим необходимый теоретический материал.
Команды пересылки адреса
LEA – Load Effective Address – загрузить эффективный адрес (смещение) операнда источник в приемник.
LEA Reg, Mem.
Команда эквивалентна команде MOV Reg, offset Mem
Команда LEA вычисляет смещение операнда-источника команды (который должен быть операндом в памяти) и сохраняет его в 16-разрядном регистре – приемнике. Следовательно, источником является относительный адрес операнда, находящегося в памяти, но не его значение! Сегментные регистры использовать нельзя.
Команда на флаги не влияет.
16-ричный код (1 байт) |
MOD Reg/OPC Reg/Mem (2-ой байт) |
смещение disp_Lo, disp_Hi |
формат операндов: приемник, источник |
8D |
MOD Reg Mem |
Disp_Lo, Disp_Hi |
Reg16, Mem16 |
MOD не может быть равно 11 !
Примеры команд:
1. Мнемоническая запись: LEA AX, [BX+SI] ; формат операндов Reg16, Mem16
Машинный код команды: 10001101 00000000 ; команда занимает 2 байта
16-ричный код команды: 8D00h.
2. Мнемоническая запись: LEA SI, [BX+88h] ; формат операндов Reg16, Mem16
Машинный код команды: 10001101 01110111 10001000 ; команда занимает 3 байта
16-ричный код команды: 8D7788h.
ПРИМЕР
Произвести деление: t1/b1 (двойного слова на слово)
................
b1 dw 5
t1 dd 1F45706Ah
................
LEA bx,t1 ; адрес t1 загружается в bx
MOV ax,[bx]; младшее слово двойного слова загружается
; в AX (706Ah)
MOV DX,[bx+2] ; старшее слово — в DX (1F45h)
IDIV b1 ; DX,AX/b1, частное — в ax
Здесь можно было бы использовать операцию WORD PTR, но это другой способ.
2) Lds и les (Load ds и Load es) — команды загрузки адреса, состоящего из двух слов, в пару регистров (сегментный регистр и, чаще всего, базовый).
LDS регистр, переменная (двойное слово)
LES регистр, переменная (двойное слово)
Младшее слово, находящееся в переменной, загружается в регистр (1-ый операнд), старшее слово — в сегментный регистр DS (если LDS) и ES (если LES).
Пример
t1 dd 565A0053h ; дальний адрес
……………..
LDS bx,t1 ; в DS запишется сегментный адрес 565Ah
; а в BX — 0053h
LES bp,t1 ; аналогично, только номер сегмента — в ES,
; а смещение в BP
jmp FAR DS:[BX] ; при этом будет происходить переход в дру-
jmp FAR ES:[BP] ; гой сегмент кода.
Таким образом, команды пересылки адреса LES и LDS позволяют организовать переход в другой сегмент по заранее заготовленному адресу. То есть заранее в памяти в переменной t1 каким-то образом формируют два слова: номер сегмента и смещение, а затем их засылают, например, с помощью команды LDS в DS и в BX. Это дает возможность адресоваться к другому сегменту.
Команды LDS и LES часто используются в системном программировании, когда пишутся собственные обработчики прерываний, и нужно переходить между сегментом кода своей программы и сегментом кода стандартных обработчиков.
Команды цикла
Как и в языках высокого уровня, циклы в ассемблере можно строить несколькими способами. Первый — использовать команды условной передачи управления. Однако в ассемблере существуют и специальные команды для организации цикла (с постусловием.): LOOP, LOOPZ (LOOPE), LOOPNZ (LOOPNE).
LOOP – LOOP according to CX – управление циклом со счетчиком в СХ
LOOP <короткая_метка> — основная команда цикла.
Действие: выполнить декремент содержимого регистра СХ, проанализировать регистр СХ: если СХ=0 передать управление следующей за LOOP команде, иначе передать управление команде, метка которой указана в качестве операнда. Обычно LOOP – последняя команда цикла. Смещение метки относительно текущего значения регистра IP должно быть в диапазоне от -128 до +127 байт. Не влияет на флаги.
Счетчик считается установленным в регистре CX (или ECX для процессора выше i386). Таким образом, в программе цикл обычно выглядит следующим образом:
.........
mov cx,<количество повторений> ; подготовка к циклу
.........
метка: ; метка начала цикла
. . . . . ; тело цикла
LOOP метка
.........
Цикл выполняется хотя бы один раз, дальше команда LOOP уменьшает содержимое регистра CX на 1 и передает управление операнду короткая_метка, если содержимое CX не равно 0, в противном случае — выход из цикла.
ПРИМЕРЫ
1) Определить результат выполнения следующего фрагмента программы.
..........
mov ax,0
mov cx,4
M1: ADD ax,cx
LOOP M1
..........
Сумма накапливается в AX: 4+3+2+1
2) Написать программу, вычисляющую сумму элементов таблицы, состоящей из слов.
..........
tabl DW 5,6,7,10,0,15,17,0,3
sum DW ? ; переменная для результата
..........
MOV cx,9 ; подготовка
MOV ax,0 ; к
MOV si,0 ; циклу
met: ; метка начала цикла
ADD ax,tabl[si] ; суммирование элементов
ADD si,2 ; переход к следующему элементу таблицы
LOOP met ; конец цикла
MOV sum,ax
..........
3) Написать программу, вычисляющую сумму только положительных элементов таблицы чисел.
..........
tabl DW 5,6,7,10,0,15,17,0,3
sum DW ? ; переменная для результата
..........
MOV cx,9 ; подготовка
MOV ax,0 ; к
MOV si,0 ; циклу
met: ; метка начала цикла
CMP tabl[si],0
JLE dop_met ; переход если меньше либо равно
ADD ax,tabl[si] ; суммирование элементов
dop_met:
ADD si,2 ; переход к следующему элементу таблицы
LOOP met ; конец цикла
MOV sum,ax
..........
Здесь добавилась команда сравнения элемента таблицы с 0. Если число не положительное, то сложение пропускается, только происходит переход на следующий элемент таблицы. В противном случае, если число положительное, оно добавляется к сумме
Обратите внимание на формат команды LOOP — тело цикла должно помещаться в пределах 127 байтов. А если тело цикла больше? В этом случае нельзя использовать команду LOOP, а нужно использовать команду условной передачи управления и директиву .386.
ПРИМЕРЫ
В программе был цикл:
..........
MOV cx,10
met:
..........; тело цикла
LOOP met
..........
Потом программу модифицировали, и оказалось, что тело цикла стало больше 127 байтов. Транслятор стал выдавать ошибку.
Изменить программу, заменив команду LOOP на команду условного перехода.
.386
..........
MOV cx,10
met:
..........
; тело цикла
DEC cx
CMP cx,0
JNZ met
..........