Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Команды цикла
Для организации циклов на Ассемблере вполне можно использовать команды условного перехода. Например, цикл языка Паскаль с предусловием while X< 0 do S; можно реализовать в виде следующего фрагмента на Ассемблере L: cmp X, 0; Сравнить X с нулём jge L1 ; Здесь будет оператор S jmp L L1:... Оператор цикла с постусловием repeat S 1; S 2;...Sk until X< 0; можно реализовать в виде фрагмента на Ассемблере L:; S 1 ; S 2 ... ; Sk cmp X, 0; Сравнить X с нулём jge L ... В этих примерах мы считаем, что тело цикла по длине не превышает примерно 120 байт (это 30-40 машинных команд). Как видим, цикл с постусловием требует для своей реализации на одну команду меньше, чем цикл с предусловием. Как мы знаем, если число повторений выполнения тела цикла известно до начала исполнения этого цикла, то в языке Паскаль наиболее естественно было использовать цикл с параметром. Для организации цикла с параметром в Ассемблере можно использовать специальные команды цикла. Команды цикла, по сути, тоже являются командами условного перехода и, как следствие, реализуют только близкий короткий относительный переход. Команда цикла loop L; Метка L заменится на операнд i8 использует неявный операнд – регистр CX и её выполнение может быть так описано с использованием Паскаля: Dec(CX); {Это часть команды loop, поэтому флаги не меняются! } if CX< > 0 then goto L; Как видим, регистр CX (который так и называется регистром счётчиком цикла – loop counter), используется этой командой именно как параметр цикла. Лучше всего эта команда цикла подходит для реализации цикла с параметром языка Паскаль вида for CX: =N downto 1 do S; Этот оператор можно эффективно реализовать таким фрагментом на Ассемблере: mov CX, N jcxz L1 L:...; Тело цикла – ...; оператор S loop L L1:... Обратите внимание, так как цикл с параметром языка Паскаль по существу является циклом с предусловием, то до начала его выполнение проверяется исчерпание значений для параметра цикла с помощью команды условного перехода jcxz L1, которая именно для этого и была введена в язык машины. Ещё раз напоминаем, что команды циклов не меняют флагов. Описанная выше команда цикла выполняет тело цикла ровно N раз, где N – беззнаковое число, занесённое в регистр-счётчик цикла CX перед началом цикла. К сожалению, никакой другой регистр нельзя использовать для этой цели (т.к. это неявный параметр команды цикла). Кроме того, в приведённом выше примере реализации цикла тело этого не может быть слишком большим, иначе команда loop L не сможет передать управление на метку L. В качестве примера использования команды цикла решим следующую задачу. Требуется ввести беззнаковое число N< =500, затем ввести N знаковых целых чисел и вывести сумму тех из них, которые принадлежат диапазону –2000..5000. Можно предложить следующее решение этой задачи. include io.asm ; файл с макроопределениями для макрокоманд ввода-вывода data segment N dw? S dw 0; Начальное значение суммы = 0 T1 db ′ Введите N< =500 $′ T2 db ′ Ошибка – большое N! $′ T3 db ′ Вводите целые числа′, 10, 13, ′ $′ T4 db ′ Ошибка – большая сумма! $′ data ends stack segment stack dw 64 dup (?) stack ends code segment assume cs: code, ds: data, ss: stack start: mov ax, data mov ds, ax mov dx, offset T1; Приглашение к вводу Outstr inint N cmp N, 500 jbe L1 mov dx, offset T2; Диагностика от ошибке Err: outstr
|