МИНИСТЕРСТВО ВЫСШЕГО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ
федеральное государственное бюджетное образовательное учреждение высшего образования
УЛЬЯНОВСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
Факультет информационных систем и технологий Кафедра «Измерительно-вычислительные комплексы»
Лабораторная работа №6
По дисциплине «Организация ЭВМ и систем»
Тема: «Работа со строчными переменными»
Выполнил: ст. гр. ИСТбд-22 Тагашев И.И.
Проверил: к.т.н., доцент ИВК Тамьяров А.В.
Ульяновск, 2021 г.
ЛАБОРАТОРНАЯ РАБОТА № 6
«Работа со строчными переменными»
Цель работы: Освоение способов работы с памятью посредством строковых инструкций.
Ход работы:
1. Строковые инструкции перемещения данных
Строковые инструкции перемещения данных во многом аналогичны инструкции MOV, но могут выполнять больше функций, чем инструкция MOV и работают быстрее. Рассмотрим сначала инструкцию LODS. Заметим, что во всех строковых инструкциях флаг указания направления (DF) задает направление, в котором изменяются регистры-указатели.
Инструкция LODS
Инструкция LODS, которая загружает байт или слово из памяти в аккумулятор (накопитель), подразделяется на две инструкции - LODSB и LODSW (B – Bite (Байт), W – Word (слово или два байта)). Инструкция LODSB загружает байт, адресуемый с помощью пары регистров DS:SI, в регистр AL и уменьшает или увеличивает регистр SI (в зависимости от состояния флага направления). Если флаг направления равен 0 (сброшен с помощью инструкции CLD (CLEAR D – сбросить флаг DF), то регистр SI увеличивается, а если флаг направления равен 1 (установлен с помощью инструкции STD (SET D – установить флаг DF), то регистр SI уменьшается. И это верно не только для инструкции LODSB, флаг направления управляет направлением, в котором изменяются все регистры-указатели строковых инструкций.
Например, в следующем фрагменте программы:
CLD
MOV SI,0
LODSB
инструкция LODSB загружает регистр AL содержимым байта со смещением 0 в сегменте данных и увеличивает значение регистра SI на 1. Это эквивалентно выполнению следующих инструкций:
MOV SI,0
MOV AL,[SI]
INC SI
однако инструкция LODSB работает существенно быстрее (и занимает на два байта меньше), чем инструкции:
MOV AL,[SI]
INC SI
Инструкция LODSW аналогична инструкции LODSB. Она сохраняет в регистре АХ слово, адресуемое парой регистров DS:SI, а значение регистра SI уменьшается или увеличивается на 2, а не на 1. Например, инструкции:
STD
MOV SI, 10
LODSW
загружают слово со смещением 10, начиная с адреса, на который указывает сегментный регистр DS (сегмент данных), в регистр АХ, а затем значение SI уменьшается на 2.
Инструкция STOS
Инструкция STOS - это дополнение инструкции LODS. Она записывает значение размером в байт или слово из аккумулятора в ячейку памяти, на которую указывает пара регистров ES:DI, а затем увеличивает или уменьшает DI. Инструкция STOSB записывает байт, содержащийся в регистре AL, в ячейку памяти по адресу ES:DI, a затем увеличивает или уменьшает регистр DI, в зависимости от флага направления. Например, инструкции:
STD
MOV DI,0FFFFH
MOV AL,55H
STOSB
записывают значение 55h в байт со смещением 0FFFFh в сегменте, на который указывает регистр ES, а затем уменьшает DI до значения 0FFFEh.
Инструкция STOSW работает аналогично, записывая значение размером в слово, содержащееся в регистре АХ, по адресу ES:DI, a затем увеличивает или уменьшает значение регистра DI на 2. Например, инструкции:
CLD
MOV DI,0FFEH
MOV AL,102H
STOWS
записывают значение 102h размером в слово, записанное в регистре АХ, по смещению OFFEh в сегменте, на который указывает регистр ES, а затем значение регистра DI увеличивается до l000h.
Инструкция MOVS
Инструкция MOVS аналогична инструкциям LODS и STOS, если их объединить в одну инструкцию. Эта инструкция считывает байт или слово, записанное по адресу DS:SI, а затем записывает это значение по адресу, определяемому парой регистров ES:DI. Слово или байт не передается при этом через регистры, поэтому содержимое регистра АХ не изменяется. Инструкция MOVSB имеет минимально возможную для инструкции длину. Она занимает только один байт, а работает еще быстрее, чем комбинация инструкций LODS
и STOS.
2. Повторение строковой инструкции
Для повторения строковой инструкции необходимое количество раз существует префикс REP (от английского REPEAT - повтор). Префикс инструкции изменяет работу последующей инструкции. Префикс REP делает следующее: он указывает, что последующую инструкцию нужно повторно выполнять до тех пор, пока содержимое регистра СХ (регистр – счетчик) не станет равным 0. (Если регистр СХ равен 0 в начале выполнения инструкции, то инструкция выполняется 0 раз, другими словами, никаких действий не производится. Этим команда REP отличается от команды организации цикла LOOP, которая при нулевом значении CX повторится 65535 раз, т.к. сначала происходит уменьшение, затем проверка.)
Префикс REP вызывает повторение только строковой инструкции.
Инструкция типа:
REP MOV AX,[BX]
не имеет смысла. В этом случае префикс REP игнорируется и выполняется инструкция:
MOV AX,[BX]
А инструкция
REP STOSB
выполнит запись из регистра AL в ячейки памяти, начиная с ячейки
ES:DI, до адреса ES:DI + CX.
3. Поиск данных с помощью строковой инструкции
Инструкция SCAS
Инструкция SCAS используется для просмотра памяти и поиска совпадения или несовпадения с конкретным значением размером в байт или слово. Как и все строковые инструкции, инструкция SCAS имеет две формы -
SCASB и SCASW.
Инструкция SCASB сравнивает содержимое регистра AL с байтовым значением по адресу ES:DI, устанавливая при этом флаги, отражающие результат сравнения (как при выполнении инструкции СМР). Как и при выполнении инструкции STOSB, при выполнении инструкции SCASB увеличивается или уменьшается значение регистра DI.
Строковые инструкции никогда не устанавливают флаги таким образом, чтобы они отражали изменения значений регистров SI, DI и/или СХ. Инструкции STOS и MOVS вообще не изменяют никаких флагов, а инструкции SCAS и CMPS изменяют флаги только в соответствии с результатом выполняемого ими сравнения.
Префикс REP распространяется так же и на команды поиска. Однако может оказаться желательным прекратить выполнение цикла в случае совпадения или несовпадения. Для этого существует две формы префикса REP, которые можно использовать с инструкцией SCAS (и с CMPS) - REPE и REPNE.
Префикс REPE (который также называется префиксом REPZ) указывает процессору, что инструкцию SCAS (или CMPS) нужно повторять до тех пор, пока регистр СХ не станет равным нулю, или пока не произойдет несовпадение. Префикс REPE можно рассматривать, как префикс, означающий "повторять, пока равно". Аналогично, префикс REPNE (KEPNZ) указывает процессору, что инструкцию SCAS (CMPS) нужно повторять, пока СХ не станет равным нулю или пока не произойдет совпадения. Префикс KEPNE можно рассматривать, как префикс "повторять, пока не равно".
Как и все строковые инструкции, инструкция SCAS увеличивает регистр-указатель DI, если флаг направления равен 0 (очищен с помощью инструкции CLD), и увеличивает DI, если флаг направления равен 1 (установлен с помощью инструкции STD).
Инструкция SCASW - это форма инструкции SCASB для работы со словом. Она сравнивает содержимое регистра АХ с содержимым памяти по адресу ES:DI и увеличивает или уменьшает значение регистра DI в конце каждого выполнения на 2, а не на 1.
Инструкция CMPS
Инструкция CMPS позволяет выполнять сравнение двух байт или слов. При одном выполнении инструкции CMPS сравниваются две ячейки памяти, а затем увеличиваются регистры SI и DI. Инструкцию CMPS можно рассматривать, как аналог инструкции MOVS, который вместо копирования
одной ячейки памяти в другую сравнивает две ячейки памяти.
Инструкция CMPSB сравнивает байт по адресу DS:SI с байтом по адресу ES:DI, устанавливая соответствующим образом флаги и увеличивая или уменьшая регистры SI и DI (в зависимости от флага направления). Регистр АL при этом не изменяется.
Инструкция CMPSW аналогична инструкции CMPSB, отличие состоит в том, что производится сравнение слов.
ЗАДАНИЕ №1
.data
L dd n/2-1 ;левая граница неотсортированного массива R dd n-1 ;правая граница неотсортированного массива
.code
;массив преобразуется в отображение пирамиды - вызвать процедуру ;down_heap n/2 раз для преобразования массива в пирамиду
b0: call down_heap
dec L ;while ( L > 0 ) L--; jnz short b0
;собственно пирамидальная сортировка dec L ;L=0
dec R ;R=n-2
b1: mov edx,R ;отправляем значение максимального mov eax,array ;элемента в конец массива
xchg eax,array[edx*4+4] ; array[0] <--> array[R]; mov array,eax
call down_heap ;восстанавливаем пирамиду - на ее ;вершине появляется новое максимальное значение
dec R ;уменьшаем индекс последнего элемента jnz short b1 ;while ( R > 0 ) R--;
b2: ...
;-----------------------------------------------------
down_heap proc; процедура вставки элемента на свое место в пирамиду mov eax,L
mov ebx,eax ;i = L; shl eax,1 ;j = 2*L;
mov esi,array[eax*2] ;item = array[L];
cmp eax,R ;if( j<R && array[j] < array[j+1]) j++; jnb short a0
mov edx,array[eax*4]
cmp edx,array[eax*4+4] ;array[j] < array[j+1] ? jnb short a0
; условие j<R && array[j]<array[j+1] выполнилось inc eax ;j++
a0: cmp eax,R ;while( j£R && item < array[j]) ja short a1
mov edi,array[eax*4]
cmp esi,edi ;item < array[j] ? jnb short a1
; условие j<=R && item < array[j] выполнилось mov array[ebx*4],edi ;array[i] = array[j]; mov ebx,eax ;i = j;
shl eax,1 ;j = 2*j; cmp eax,R
jnb short a0;if( j<R && array[j] < array[j+1]) j++; mov edx,array[eax*4]
cmp edx,array[eax*4+4] jnb short a0
; условие j<R && array[j] < array[j+1] выполнилось inc eax ;j++
jmp short a0
a1: mov array[ebx*4],esi ;array[i] = item; retn
down_heap endp
ЗАДАНИЕ №2
masm |
|
|
|
|
|
model |
small |
||||
.data |
|
|
|
|
|
var1 db |
12 |
|
|
|
|
.stack |
256h |
||||
.code |
|
|
|
|
|
main proc |
|||||
|
|
|
|
|
|
mov |
ah |
,var1 |
|||
|
|
|
|
|
|
mov |
ds |
:[0000h], |
ah |
||
mov |
al |
, |
ds |
:[0000h] |
|
mov |
ax |
,4c00h |
|||
int |
21h |
main endp end main
Вывод: Получено освоение способов работы с памятью посредством строковых инструкций.