Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
97
Добавлен:
11.02.2014
Размер:
310.27 Кб
Скачать

Контрольные вопросы:

  1. Чем отличается выполнение арифметических операций на языке ассемблера от языков высокого уровня?

  2. По какому биту регистра флагов можно установить, что предшествующее вычитание привело к отрицательному результату?

  3. По какому биту регистра флагов можно установить, что в результат арифметической операции превысил разрядную сетку?

  4. В чем особенность выполнения арифметических операций с знаковыми и безнаковыми числами?

  5. Назначение команды IMUL и ее основное отличие от команды MUL?

  6. В чем особенность битовых команд от других команд языка ассемблера?

  7. Как отражается на регистре флагов выполнение логических команд?

  8. Опишите схематически работу одну из команд сдвигов?

  9. В каком регистре необходимо указывать величину сдвига в команда сдвига?

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

К

Составитель: преп.каф.Информатики

Аркабаев Нуркасым Кылычбекович

оманды перехода и сравнения. Циклы

Цель работы:

  • изучить команды безусловного перехода языка ассемблера;

  • изучить команды условного перехода;

  • научить организацию циклов на ассемблере;

Теоретическая часть

Лишь в самых простых программах команды выполняются в порядке их размещения в памяти. Изменение естественного порядка выполнения команд обеспечивается с помощью команд передачи управления, весь набор которых можно разделить на 3 группы: команды безусловной передачи управления, команды условной передачи управления, команды управления циклами.

К первой группе относятся команды безусловных переходов и команды вызова процедур (безусловных переходов с возвратом). Команды вызова процедур будут рассмотрены в следующей работе.

Безусловные переходы

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

mov ax,1

jmp metka

add ax,5

metka:

inc ax

регистр AX будет содержать значение 2, а инструкция ADD, следующая за меткой metka не будет выполнена. Здесь инструкция jmp указывает процессору 8086, что нужно установить указатель инструкций IP в значение смещения метки metka, поэтому следующей выполняемой инструкцией будет инструкция inc ax

Инструкцию JMP можно использовать для перехода в другой сегмент кода, загружая в одной инструкции и регистр CS, и регистр IP. Если вы хотите, чтобы метка принудительно интерпретировалась, как метка дальнего типа, можно использовать операцию FAR PTR.

Наконец, вы можете выполнить переход по адресу, записанному в регистре или в переменной памяти. Например:

mov ax,OFFSET TestLabel

jmp ax

...

TestLabel:

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

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

Инструкция условного перехода может осуществлять или нет переход на целевую (указанную в ней) метку, в зависимости от состояния регистра флагов. Рассмотрим следующий пример:

mov ah,1 ; функция DOS ввода с клавиатуры

int 21h ; получить следующую нажатую клавишу

cmp al,'A' ; была нажата буква "A"?

je AwasTyped ; да, обработать ее

mov [TampByte], al ; нет, сохранить символ

...

AWasTyped:

push ax ; сохранить символ в стеке

Сначала в данной программе с помощью функции операционной системы DOS воспринимается нажатая клавиша. Затем для сравнения введенного символа с символом 'A' используется инструкция CMP. Эта инструкция аналогична инструкции SUB, только ее выполнение ни на что не влияет, поскольку назначение данной инструкции состоит в том, чтобы можно было сравнить два операнда, установив флаги так же, как это делается в инструкции SUB. Поэтому в предыдущем примере флаг нуля устанавливается в значение 1 только в том случае, если регистр AL содержит символ A.

Теперь мы подошли к основному моменту. Инструкция JE представляет инструкцию условного перехода, которая. осуществляет передачу управления только в том случае, если флаг нуля равен 1. В противном случае выполняется инструкция, непосредственно следующая за инструкцией JE (в данном случае - инструкция MOV). Флаг нуля в данном примере будет установлен только в случае нажатия клавиши A, и только в этом случае процессор 8086 перейдет к выполнению инструкции с меткой AWasTyped, то есть инструкции PUSH.

Перечень инструкций условных переходов приводится в Таблице 1.

Инструкции условных переходов Таблица 1

Мнемоника

Перейти, если...

Условие перехода

JA(JNBE)

Выше

CF=0иZF=0

JAE(JNB,JNC)

Выше или равно

CF=0

JB(JNAE,JC)

Ниже

CF=1

JBE(JNA)

Ниже или равно

CF=1 или ZF=1

JE(JZ)

Равно

ZF=1

JNE(JNZ)

Не равно, не нуль

ZF=0

JCXZ

CX=0

CX=0

JP

Четное количество единиц

PF=1

JNP(JPO)

Нечетное количество единиц

PF=0

JG(JNLE)

Больше

ZF=0 и SF=0

JGE(JNLE)

Больше или равно

SF=OF

JL(JNGE)

Меньше

SF<>OF

JO

Есть перенос

OF=1

JNO

Нет переноса

OF=0

JS

Флаг знака установлен

SF=1

JNS

Флаг знака сброшен

SF=0

CF - флаг переноса, SF - флаг знака, OF - флаг переполнения, ZF - флаг нуля, PF - флаг четности

Циклы

Для чего используются циклы? Они служат для работы с массивами, проверки состояния портов ввода-вывода до получения определенного состояния, очистки блоков памяти, чтения строк с клавиатуры и вывода их на экран и т.д. Циклы - это основное средство, которое используется для выполнения повторяющихся действий. Поэтому используются они довольно часто, настолько часто, что в наборе инструкций процессора 8086 предусмотрено фактически несколько инструкций циклов: LOOP, LOOPNE, 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 ; обработать следующий

; символ, если он имеется

..

Есть, однако, лучший способ. Возможно, вспомните, что ранее уже упоминалось о том, что регистр CX весьма полезно бывает использовать для организации циклов. Инструкция:

loop PrintStringLoop

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

dec cx

jnz PrintStringLoop

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

Соседние файлы в папке лабораторные работы по ASSAMBLER