Команды передачи управления
По принципу действия, команды микропроцессора, обеспечивающие организацию переходов в программе, можно разделить на три группы: 1. Команды безусловной передачи управления: - команда безусловного перехода; jmp - вызова процедуры и возврата из процедуры; call, ret - вызова программных прерываний и возврата из программных прерываний. Int, iret 2. Команды условной передачи управления: - команды перехода по результату команды сравнения cmp; - команды перехода по состоянию определенного флага; - команды перехода по содержимому регистра ecx/cx. 3. Команды управления циклом: - команда организации цикла со счетчиком ecx/cx; - команда организации цикла со счетчиком ecx/cx с возможностью досрочного выхода из цикла по дополнительному условию. jmp адрес_перехода - безусловный переход без сохранения информации о точке возврата. Аналог goto. jmp m1 m4: … … m1: jmp m4
Условные переходы Команды условного перехода имеют одинаковый синтаксис: jcc метка_перехода Мнемокод всех команд начинается с “ j ” — от слова jump (прыжок), cc — определяет конкретное условие, анализируемое командой. Что касается операнда метка_перехода, то эта метка может находится только в пределах текущего сегмента кода, межсегментная передача управления в условных переходах не допускается. Для того чтобы принять решение о том, куда будет передано управление командой условного перехода, предварительно должно быть сформировано условие, на основании которого и будет приниматься решение о передаче управления. Источниками такого условия могут быть:
- любая команда, изменяющая состояние арифметических флагов; - команда сравнения cmp, сравнивающая значения двух операндов; - состояние регистра ecx/cx.
Условные переходы по содержимому флагов
jcxz метка_перехода (Jump if cx is Zero) — переход, если cx ноль; jecxz метка_перехода (Jump Equal ecx Zero) — переход, если ecx ноль.
Пример программы: определите, равны ли два числа вводимые пользователем с клавиатуры. Model small Stack 100h Data s1 db 'числа равны$' s2 db 'числа не равны$' .code start: mov ax,@data mov ds,ax mov ah,01h int 21h;ввели первое число mov dl,al mov ah,01h int 21h;ввели второе число sub al,dl;сравнили числа jnz m1 mov dx, offset s1 jmp m2 m1: mov dx, offset s2 m2: mov ah,09h int 21h;выводим информационную строку Mov ax,4 c 00 h Int 21h End start
Команда сравнения cmp cmp операнд_1,операнд_2 - сравнивает два операнда и по результатам сравнения устанавливает флаги. Команда сравнения cmp имеет интересный принцип работы. Он абсолютно такой же, как и у команды вычитания sub. Единственное, чего она не делает — это запись результата вычитания на место первого операнда. Алгоритм работы: -выполнить вычитание (операнд1-операнд2); -в зависимости от результата установить флаги, операнд1 и операнд2 не изменять (то есть результат не запоминать).
Условные переходы после команд сравнения
Пример программы: определите, равны ли два числа вводимые пользователем с клавиатуры. Model small Stack 100h Data s1 db 'числа равны$' s2 db 'числа не равны$' .code start: mov ax,@data mov ds,ax mov ah,01h int 21h;ввели первое число mov dl,al mov ah,01h int 21h;ввели второе число cmp al,dl;сравнили числа jne m1 mov dx, offset s1 jmp m2 m1: mov dx, offset s2 m2: mov ah,09h int 21h;выводим информационную строку Mov ax,4 c 00 h Int 21h end start
Организация циклов loop метка_перехода (Loop) — повторить цикл Работа команды заключается в выполнении следующих действий: - декремента регистра ecx/cx; - сравнения регистра ecx/cx с нулем: - если (ecx/cx) > 0, то управление передается на метку перехода; - если (ecx/cx) = 0, то управление передается на следующую после loop команду mov cx, количество циклов м1: тело цикла loop m1 loope/loopz метка_перехода (Loop till cx <> 0 or Zero Flag = 0) — повторить цикл, пока cx <> 0 или zf = 0. loopne/loopnz метка_перехода (Loop till cx <> 0 or Not Zero flag=0) — повторить цикл пока cx <> 0 или zf = 1 Недостаток команд организации цикла loop, loope/loopz и loopne/loopnz в том, что они реализуют только короткие переходы (от –128 до +127 байт). Организация вложенных циклов mov cх,n; в сх заносим количество итераций внешнего цикла m1: push cx … mov cx,n1; в сх заносим количество итераций внутреннего цикла m2: тело внутреннего цикла loop m2 … pop cx loop m1
Пример программы: Напишите программу подсчета у=1+2+3+…+n, n не более 10000.
model small .stack 100h .data yb dd? ym dw? s1 db 'введите n',10,13,'$' .code start: mov ax,@data mov ds,ax
mov dx, offset s1 mov ah,09h int 21h mov cx,3 m: shl bx,4 mov ah,01h int 21h вводим n в регистр bx sub ax,130h add bx,ax loop m
mov cx,bx xor dx,dx xor al,al m1: add dx,cx считаем у jnc m2 mov al,1 m2: loop m1
cmp al,1 je m3 mov ym,dx m3: mov yb,edx
mov ax,4c00h int 21h end start Цепочечные команды (Команды обработки строк символов)
Цепочка – это последовательность элементов, размер которых может быть байт, слово, двойное слово. Содержимое этих элементов может быть любое – символы, числа. В системе команд микропроцессора имеется семь операций-примитивов обработки цепочек. Каждая из них реализуется в микропроцессоре тремя командами, в свою очередь, каждая из этих команд работает с соответствующим размером элемента — байтом, словом или двойным словом. Вместе с цепочечными командами обычно применяют префиксы повторений, которые ставятся перед командой в поле [метки]. Цепочечная команда без префикса выполняется один раз. С префиксом цепочечные команды выполняются циклично. rep (REPeat) - команда выполняется, пока содержимое в ecx/cx не станет равным 0. При этом цепочечная команда, перед которой стоит префикс, автоматически уменьшает содержимое ecx/cx на единицу. Та же команда, но без префикса, этого не делает. repe или repz (REPeat while Equal or Zero) - команда выполняется до тех пор, пока содержимое ecx/cx не равно нулю или флаг zf равен 1. Как только одно из этих условий нарушается, управление передается следующей команде программы repne или repnz (REPeat while Not Equal or Zero) - команда циклически выполняется до тех пор, пока содержимое ecx/cx не равно нулю или флаг zf равен нулю. При невыполнении одного из этих условий работа команды прекращается. Формирования физического адреса операндов адрес_источника и адрес_приемника происходит следующим образом: адрес_источника — пара ds:esi/si; адрес_приемника — пара es:edi/di Важный момент, касающийся всех цепочечных команд, — это направление обработки цепочки. Есть две возможности: - от начала цепочки к ее концу, то есть в направлении возрастания адресов; - от конца цепочки к началу, то есть в направлении убывания адресов. Цепочечные команды сами выполняют модификацию регистров, адресующих операнды, обеспечивая тем самым автоматическое продвижение по цепочке. Количество байт, на которые эта модификация осуществляется, определяется кодом команды. А вот знак этой модификации определяется значением флага направления df (Direction Flag) в регистре eflags/flags. Состоянием флага df можно управлять с помощью двух команд, не имеющих операндов:
cld (Clear Direction Flag) — очистить флаг направления df = 0, значение индексных регистров esi/si и edi/di будет автоматически увеличиваться (операция инкремента) цепочечными командами, то есть обработка будет осуществляться в направлении возрастания адресов; std (Set Direction Flag) — установить флаг направления df = 1, то значение индексных регистров esi/si и edi/di будет автоматически уменьшаться (операция декремента) цепочечными командами, то есть обработка будет идти в направлении убывания адресов. Типовой набор действий для выполнения любой цепочечной команды: - Установить значение флага df в зависимости от того, в каком направлении будут обрабатываться элементы цепочки — в направлении возрастания или убывания адресов. - Загрузить указатели на адреса цепочек в памяти в пары регистров ds:(e)si и es: (e)di. - Загрузить в регистр ecx/cx количество элементов, подлежащих обработке. - Выдать цепочечную команду с префиксом повторений. Пересылка цепочек movs адрес_прием, адрес_источника (MOVe String)- переслать цепочку; movsb MOVe String Byte) — переслать цепочку байт; movsw (MOVe String Word) — переслать цепочку слов; movsd (MOVe String Double word) — переслать цепочку двойных слов. Команда копирует байт, слово или двойное слово из цепочки источника, в цепочку приемника. Размер пересылаемых элементов ассемблер определяет, исходя из атрибутов идентификаторов. К примеру, если эти идентификаторы были определены директивой db, то пересылаться будут байты, если идентификаторы были определены с помощью директивы dd, то пересылке подлежат двойные слова. Для цепочечных команд с операндами типа movs адрес_приемника,адрес_источника, не существует машинного аналога. При трансляции в зависимости от типа операндов транслятор преобразует ее в одну из трех машинных команд: movsb, movsw или movsd. Сама по себе команда movs пересылает только один элемент, исходя из его типа, и модифицирует значения регистров esi/si и edi/di. Если перед командой написать префикс rep, то одной командой можно переслать до 64 Кбайт данных. Число пересылаемых элементов должно быть загружено в счетчик — регистр cx (use16) или ecx (use32). Пример проги. Пересылка строк командой movs MODEL small STACK 256 .data source db 'Тестируемая строка','$';строка-источник dest db 19 DUP (' ');строка-приёмник .code main: mov ax,@data ;загрузка сегментных регистров mov ds,ax ;настройка регистров DS и ES на адрес сегмента данных mov es,ax cld ;сброс флага DF — обработка строки от начала к концу lea si,source ;загрузка в si смещения строки-источника
lea di,dest ;загрузка в DS смещения строки-приёмника mov cx,20 ;для префикса rep — счетчик повторений (длина строки) rep movs dest,source;пересылка строки lea dx,dest mov ah,09h;вывод на экран строки-приёмника int 21h mov ax,4c00h int 21h end main
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|