Добавил:
vanya.tagaschev@ya.ru Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
4
Добавлен:
21.03.2021
Размер:
27.21 Кб
Скачать

МИНИСТЕРСТВО ВЫСШЕГО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ

федеральное государственное бюджетное образовательное учреждение высшего образования

УЛЬЯНОВСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ

Факультет информационных систем и технологий

Кафедра «Измерительно-вычислительные комплексы»

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

По дисциплине «Организация ЭВМ и систем»

Тема: «Условные переходы. Организация циклов.»

Выполнила:

ст. гр. ИСТбд-22 Довледмурадова Акджагул

Проверил:

к.т.н., доцент ИВК Тамьяров А.В.

Ульяновск, 2021 г.

ЛАБОРАТОРНАЯ РАБОТА № 5

Тема: «Условные переходы. Организация циклов»

Цель работы: освоение принципов построение программ с разветвленной структурой.

Ход работы:

Условные переходы.

Условные переходы делятся на две группы: проверяющие результаты предыдущей арифметической или логической команды, и управляющие итерациями фрагмента программы. Все условные переходы имеют однобайтовое смещение. Если условный переход осуществляется на место, находящееся дальше 128 байт, нужно использовать специальную конструкцию. Например, допустим, что программе надо перейти к метке ZERO, если установлен флаг нуля эта метка находится дальше 128 байт от текущего места. Программа в этом случае выглядит примерно так:

JNZ CONTINUE

JMP ZERO

CONTINUE:

  1. Проверки кода условия

Первая группа команд условного перехода проверяет текущее состояние регистра флагов. Затем в зависимости от кодов условия команда делает переход (или не делает). Команды условного перехода не устанавливают флаги, а только проверяют их текущее состояние. Ранее рассмотренные арифметические и логические команды устанавливают флаги.

В Табл.1 показаны команды условного перехода и проверяемые ими флаги. В строках рисунка перечислены команды условного перехода, а в пяти колонках показано состояние флагов. Буква X в любой позиции означает, что команда не проверяет флаг. Цифра 0 означает, что этот флаг должен быть сброшен, чтобы условие было выполнено и переход произошел. Цифра 1 означает, что флаг должен быть установлен, чтобы переход произошел. Некоторые элементы таблицы показывают выражение, которое должно быть истинно, чтобы переход произошел. Так сделано для арифметических переходов, и мы обсудим их далее более подробно.

Таблица 1. Проверка необходимости перехода по флагам.

Команды условного перехода ! Флаги ! OF CY Z P S ! Комментарий

а) Проверки флагов

JE/JZ ! X X 1 X X !

JP/JPE ! X X X 1 X !

JO ! 1 X X X X !

JS ! X X X X 1 !

JNE/JNZ ! X X 0 X X !

JNP/JPO ! X X X 0 X !

JNO ! 0 X X X X !

JHS ! X X X X 0 !

b) Арифметика со знаком

JL/JNGE ! а X X X b ! a NEQ b

JLE/JNG ! а X 1 X b ! Z OR (A WEQ В)

JNL/JGE ! а X X X b ! а = b

JNLE/JG ! а X 0 X b ! (NOT Z) AND (a=b)

с) Беззнаковая арифметика

JB/JNAE/JC ! X 1 X X X !

JBE/JNA ! X 1 1 X X ! CY OR Z

JBB/JAE/JNC ! X 0 X X X !

JNBE/JA ! X 0 0 X X ! (NOT CY) AND (NOT Z)

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

При непосредственной проверке отдельного флага условный переход может проверить каждый из этих пяти флагов непосредственно на 0 или 1. Проверка флага переноса показана на рисунке в группе арифметики без знака, поскольку она имеет еще и арифметический смысл. Заметим, что многие команды условного перехода имеют более одной мнемоники, если даже выполняется одна и та яге проверка. Например, проверку флага нуля осуществляет команда JZ (переход, если результат операции равен нулю), Однако команда JE (переход, если равно) также порождает ту же команду. Следующая последовательность поясняет смысл этого:

СМР АХ, BХ

JE LABEL

Команда СМР вычитает содержимое регистра ВХ из содержимого регистра АХ, устанавливая флаги в соответствии с результатом. Если оба операнда равны, то результат будет нулевой и флаг нуля будет показывает равенство. Аналогично, команда JNZ (переход, если не нуль) идентичен команде JNE (переход, если не равно). Команда JP (переход по четности) - то же самое, что и команда JPE (переход при наличии четности); команда JNP (переход по нечетности) -то же самое, что команда JPO (переход при отсутствии четности).

Следующую группу команд условного перехода составляют арифметические сравнения со знаком. Существуют четыре условия, которые могут быть проверены: меньше (JL), меньше или равно (JLE), больше (JG), больше или равно (JGE). Другие четыре мнемоники - отрицания этих четырех. В случае арифметики со знаком ассемблер использует мнемонику в названии команд "меньше" (less) и "больше" (greater) . Далее мы увидим, что для арифметики без знака ассемблер использует мнемонику "выше" (above) и "ниже" (below).

Арифметические выражения можно понять, используя их вместе с командой СMР. Например,

СМР АХ,ВХ

JL LABEL

Переход произойдет, если содержимое регистра АХ меньше содержимого регистра ВХ. Вы можете читать комбинацию команд сравнения и условного перехода вместе, как один оператор: операнд результата встречается первым, затем идет условный оператор, а за ним следует исходный операнд. Другой пример:

СМР CX,WORD_IM_MEMORY

JNLE LABEL

- можно прочитать так: "переход, если содержимое регистра СХ не меньше, чем, или равен содержимому ячейки памяти WORD_IN_MEMORY. Этот прием можно использовать для определения значения любой команды арифметического перехода, учитывающей знак или не учитывающей.

Как показано в Табл.1 арифметические сравнения со знаком проверяют одновременно несколько флагов. Фактически каждая из этих команд проверяет некоторую комбинацию флагов переполнения, знака, и, возможно, флага нуля. Например, в команде JL требуется, чтобы флаги переполнения и знака имели разные значения. Если они имеют одинаковое значение, первый операнд не был меньше второго. Рассмотрим эту операцию несколько подробнее, чтобы понять работу арифметических сравнений.

Когда сравниваются два числа со знаком, возможны четыре ком­бинации флагов знака и переполнения. Рассмотрим каждую из четырех комбинаций, чтобы определить какое состояние операндов привело к данному результату. Предположим, что в каждом случае флаги уста­новила команда СМР, вычитавшая два операнда.

Знак S=0, переполнение O=0.

Условие S=0 означает, что результат вычитания положителен. Условие О=0 означает, что переполнения не было, т.е. результат, представленный в дополнительном коде, правильный. Вычитание двух чисел, дающее положительный результат, показывает, что первое число больше второго, и поэтому имеет место соотношение "больше". Однако вычитание двух равных чисел также дает положительный результат, так что условие S=0, O=0 означает "больше или равно".

S=1, O=0

В этом случае O=0 означает, что результат верен, а S=1 говорит о том, что он отрицателен. Чтобы получить отрицательный результат, большее число должно вычитаться из меньшего, и соотношение означает "меньше".

S = 0, О = 1

Здесь О=1 показывает, что результат неверен, т.е. вышел за пределы возможностей разрядной сетки. Это значит, что сложение двух положительных чисел дало отрицательный результат или наоборот. В данном случае это сравнение показывает, что знак результата неверен; поэтому результат этого сравнения идентичен случаю, когда S=1, О=0, что означает "меньше".

S = 1, О = 1

Снова О=1 говорит о том, что знак результата неверен. Поэтому вычитание должно было привести к очень большому положительному числу, и соотношение будет "больше или равно".

В некоторых случаях также учитывается флаг нуля. Например, команда JLE выполняется, если условие есть "меньше" (знак и переполнение разные) или "равно" (флаг нуля равен 1). Эти три флага позволяют микропроцессору 8086 проверить все возможные комбинации чисел со знаком.

Последняя часть табл.1 показывает условия, проверяемые для арифметики без знака. Как и в случае арифметики со знаком, существуют четыре возможные соотношения между операндами, которые может проверить микропроцессор. Для того чтобы отличить команды условного перехода ориентированные на беззнаковую арифметику от знаковой арифметики, используются слова "выше" и "ниже" в названии команд. Вероятно, этим выражается точка зрения создателей набора команд, заключающаяся в том, что арифметика без знака будет использоваться в программах для вычисления адресов, а отрицательных адресов не бывает. "Выше" и "ниже" показывают расположение значения адресов внутри адресного пространства, в то время как "больше" и "меньше" говорит о соотношении чисел со знаком. Здесь важно, что выполняется именно та команда, которая указана в программе на языке ассемблера, независимо от типов сравниваемых операндов. Например, программа сравнивает два числа со знаком, а использует команду JA (переход, если выше). Микропроцессор выполняет условный переход в зависимости от соотношения двух чисел, считая их числами без знака, т.е. именно программист обязан выбрать правильную команду условного перехода.

Микропроцессор 8086 при сравнении двух чисел без знака учитывает только два флага. Флаг переноса показывает, какое из чисел больше. Сравнение устанавливает флаг переноса, если первый операнд ниже второго или сбрасывает флаг переноса, если первый операнд либо выше, либо равен второму операнду, и флаг нуля определяет, что в данном случае верно.

Сравнения без знака можно читать так же, как и сравнения со знаком. Например,

СМР АХ,ВХ

JA LABEL

- переход на метку LABEL происходит, если регистр АХ выше регистра ВХ. Условный переход выполняется всегда, если объявленное соотношение существует между первым и вторым операндами предшествовавшей команды сравнения.

2. Организация циклов.

Одним из видов конструкций в программе, которые можно построить с помощью условных переходов, являются циклы. Цикл - это просто-напросто блок кода, завершающийся условным переходом, благодаря чему этот блок может выполняться повторно до достижения условия завершения. Циклы - это основное средство, которое используется для выполнения повторяющихся действий. Поэтому используются они довольно часто, настолько часто, что в наборе инструкций процессора 8086 предусмотрено фактически несколько инструкций циклов: LOOP, LOOPME, LOOPE и JCXZ.

Инструкция LOOP

Предположим, мы хотим вывести 17 символов текстовой строки TestString. Это можно сделать следующим образом:

.data

TestString DB ‘Это проверка! ...’

.CODE

mov cx,17

mov bx,OFFSET TestString

PrintStringLoop:

mov dl,[bx] ;получить следующий символ

inc bx ;ссылка на следующий символ

mov ah,2 ;функция DOS вывода на экран

int 21h ;вызвать DOS для вывода символа

dec cx ;уменьшить счетчик длины строки

jnz PrintStringLoop ;обработать следующий символ, если он имеется

Есть, однако, лучший способ.

Инструкция:

loop PrintStringLoop

делает то же, что и инструкции:

dec cx

jnz PrintStringLoop

однако выполняется она быстрее и занимает на один байт меньше. Всякий раз, когда вам нужно организовать цикл, пока значение счетчика не станет равным 0, запишите начальное значение счетчика в регистр СХ и используйте инструкцию LOOP.

Инструкция LOOPE

Инструкция LOOPE работает также, как инструкция LOOP, только цикл при ее выполнении будет завершаться (то есть перестанут выполняться переходы), если регистр СХ примет значение 0 или флаг нуля будет установлен в значение 1.

Инструкция LOOPNE

Инструкция LOOPHE завершает выполнение цикла, если регистр СХ принял значение 0 или флаг нуля сброшен (имеет нулевое значение).

Инструкция LOOPE известна также, как инструкция LOOP2, инструкция LOOPME - как инструкция LOOPNZ.

Инструкция JCXZ.

Имеется еще одна инструкция цикла. Это инструкция JCXZ. Инструкция JCXZ осуществляет переход только в том случае, если зна­чение регистра СХ равно 0.

Относительно инструкций циклов можно сделать несколько замечаний. Во-первых, нужно помнить о том, что инструкции циклов, как и инструкции условных переходов, могут выполнять переход только на метку, отстоящую от инструкции цикла не более чем на 128 байт в ту или другую сторону. Циклы, превышающие 128 байт, требуют использования условных переходов с помощью безусловных переходов. Во-вторых, важно понимать, что ни одна из инструкций циклов не влияет на состояние флагов. Это означает, что инструкция:

loop LoopTop

не эквивалентна в точности инструкциям:

dec cx

jnz LoopTop

поскольку инструкция DEC изменяет флаги переполнения, знака, нуля, дополнительного переноса и четности, а инструкция LOOP на флаги не влияет.

ЗАДАНИЕ №1

mov ax,1

mov cx,12 ; максимум

xor bx,bx

F: mul cx

push ax

push dx

mov ax,bx

mul cx

mov bx,ax

pop dx

add bx,dx

pop ax

loop F

; bx:ax - result

ЗАДАНИЕ №2

a db 3

b db 4

.code

begin:

mov ax,@data

mov ds,ax

mov al,a ;al=a

imul al ;ax=a^a

imul ax ;dx:ax=a^3

mov bx,dx

rol ebx,16

mov bx,ax ;ebx=a^3

;b^3

mov al,b ;al=b

imul al ;ax=b^2

imul ax ;dx:ax=b^3

mov cx,dx

rol ecx,16

mov cx,ax ;ecx=b^3

;(a^3-b^3)

sub ebx,ecx ;ebx=a^3-b^3

imul ebx ;edx:eax=(a^3-b^3)^2

rol rax,32

mov eax,edx

ror rax,32

;3ab

mov al,a ;=a

imul b ;ax=ab

cwde ;ax->eax

mov ebx,3 ;ebx=3

mul ebx,eax ;ebx=3ab

cdq ;edx:eax=3ab

mov esi,edx

mov edi,eax

;(a^3-b^3)^2-3ab

sub eax,edi

sbb edx,esi ;edx:eax=(a^3-b^3)-3ab

mov al,a ;al=a

imul al ;ax=a^2

imul ax ;edx:eax=a^3

mov cx,dx

rol ecx,16

mov cx,ax ;ecx=a^3

mov ebx,4

mov ecx,ebx ;ecx=4a^3

idiv ecx

ЗАДАНИЕ №3

org 100h

jmp start

mes0 db 13,10,'Formula: A = (3*N)^2 '

db 13,10,'---------------------'

db 13,10,'Type N: $'

mes1 db 13,10,'Result: $'

start:

mov ah,9 ;

mov dx,mes0 ;

int 21h ;

mov ah,1 ; ввод с эхом

int 21h ;

and ax,0fh ; символ --> цифра

push ax ; запомним

mov ah,9 ;

mov dx,mes1 ;

int 21h ;

pop ax ;

mov bx,3 ;

imul bx ; умножить ввод на 3

imul ax ; результ в квадрат

mov bx,10 ; вывод на экран в DEC

call hex2asc ;

exit: ;

xor ax,ax ;

int 16h ;

int 20h ;

;

hex2asc: ; Функция переводит числа в символы

pusha ; Вход: АХ = число, BX = система счисления

xor cx,cx ; Выход: на экране

isDiv: ;

xor dx,dx ;

div bx ;

push dx ;

inc cx ;

or ax,ax ;

jnz isDiv ;

isOut: ;

pop ax ;

cmp al,9 ;

jle noHex ;

add al,7 ;

noHex: ;

add al,30h ;

int 29h ;

loop isOut ;

popa ;

ret ;

Вывод: Получено освоение принципов построение программ с разветвленной структурой.

Соседние файлы в папке Тамьяров А. В.