Loop ассемблер: 503 Service Temporarily Unavailable

Команды LOOP, LOOPD, LOOPE, LOOPNE, LOOPNZ, LOOPZ

Команды LOOP, LOOPD, LOOPE, LOOPNE, LOOPNZ, LOOPZ используются для организации циклов. Счетчиком цикла служит регистр CX или ECX (в зависимости от разрядности). В командах циклов с условием (Z, NZ, E, NE) цикл выполняется пока заданное условие истинно.

 

Команды LOOP, LOOPD
Синтаксис: LOOP op1
LOOPD op1
Операнды: op1 — i8
Назначение: Цикл
Процессор: 8086+
80386+
Флаги: Не изменяются
Комментарий:
Ограничения: Нет
Примеры:

	mov	cx,100
l1:	add	ax,[bx]
	inc	bx
	loop	l1
Команды LOOPE и LOOPZ
Синтаксис: LOOPE op1
LOOPZ op1
Операнды: op1
— i8
Назначение: Цикл, пока равно (пока ноль)
Процессор: 8086+
Флаги: Не изменяются
Комментарий:
Ограничения: Поскольку все модификации команды LOOP не изменяют регистр флагов, то флаг ZF должен изменяться внутри тела цикла.
Примеры:

	mov	cx,100
l1:	add	ax,[bx]
	dec	bx
	loope	l1
Команды LOOPNE и LOOPNZ
Синтаксис: LOOPNE op1
LOOPNZ op1
Операнды: op1 — i8
Назначение: Цикл, пока не равно (пока не ноль)
Процессор: 8086+
Флаги: Не изменяются
Комментарий:
Ограничения: Поскольку все модификации команды LOOP не изменяют регистр флагов, то флаг ZF должен изменяться внутри тела цикла.
Примеры:

	mov	cx,100
l1:	add	ax,[bx]
	dec	bx
	loopne	l1

 

•Промоделируем на Ассемблере простейшую задачу для 16-разрядных знаковых и беззнаковых данных:

–unsigned int c, d;

–int a, b;

•if (a=b) then Fsign = 0;

•if (a<b) then Fsign = -1;

•if (a>b) then Fsign = 1;

•if (c=d) then Fusign = 0;

•if (c<d) then Fusign = -1;

•if (c>d) then Fusign = 1;

Команды циклов LOOPx

Группа команд условного перехода LOOPх служит для организации циклов в программах. Все команды цикла используют регистр CX в качестве счетчика цикла. Простейшая из них – команда LOOP. Она уменьшает содержимое CX на 1 и передает управление на указанную метку, если содержимое CX не равно 0. Если вычитание 1 из CX привело к нулевому результату, выполняется команда, следующая за LOOP.

Синтаксис команды: LOOP короткая метка

Логика работы команды:

СХ = Counter short_label: Выполнение тела цикла СХ = СХ — 1

if (СХ != 0) goto short_label

Аналог реализации команды LOOP на Ассемблере:

MOV СХ, Counter short_label:

;Выполнение тела цикла ;

;Проверка условия ПРОДОЛЖЕНИЯ цикла DEC СХ

СМР СХ, 0 JNE short_label

Команда LOOP уменьшает содержимое регистра СХ на 1, затем передает управление метке shorMabel, если содержимое СХ не равно 0. Передача управления на метку shortjabel для базовых процессоров — только КОРОТКАЯ

[-128,0]. Поскольку условие выхода из цикла проверяется в

КОНЦЕ, при значении Counter=0 цикл все равно выполнится. Этого мало, мы еще и зациклимся. Чтобы этого избежать,

обычно ДО НАЧАЛА ЦИКЛА проверяют содержимое регистра СХ на ноль. Таким образом, стандартная последовательность команд для организации цикла СО СЧЕТЧИКОМ имеет следующий вид:

MOV CX, Counter

JCXZ ExitCicle ; если CX = 0, цикл ОБОЙТИ short_label:

; Выполнение тела цикла LOOP short_label

ExitCicle:

ПРИМЕР

Вычислить значение факториала р = n! = 1*2*3*…*n

Известно, что 0! = 1. Отрицательным значение n быть НЕ может

.Model Large,С

 

; определение префикса для локальных меток

 

locals @@

 

 

.code

 

 

Extrn С n: Word

 

Extrn С p: Word

 

Public proizv1

 

Proizv1 Proc far ; Вариант 1

 

mov cx,n

; количество повторений

 

mov si,1

 

 

mov ax,si

 

 

jcxz @@Exit ;if cx=0 then Exit

 

@@begin: ;

= НАЧАЛО цикла

=

mul si

; <dx:ax> = <ax>*si

 

inc si

 

 

; ==== Выход из цикла ==================

loop @@beg±n @@Exit: mov p,ax

ret

proizv1 endp

Public proizv2

Proizv2 Proc far ; Вариант 2

mov cx ,n ; количество повторений mov ax,1

jcxz @@Exit ;if cx=0 then Exit @@begin: ;— = НАЧАЛО цикла =====

mul cx ; <dx:ax> = <ax>*cx

; ==== Выход из цикла =========

loop @@begin @@Exit:

mov p,ax ret

proizv2 endp end

Директива locals

Директива locals позволяет нам не думать о дублировании имен меток в разных подпрограммах. Метки с префиксом @@ считаются локальными. Если компилятор встретит метку с таким же именем, он просто при компиляции присвоит ей другое имя (обычно эти метки получают в конце имени номер, который увеличивается на единицу — все очень просто!).

Команда LOOPE (LOOPZ)

•Команда LOOPE (LOOPZ) переход по счетчику и если равно

Данная команда имеет два равнозначных мнемонических имени (if Equal — если Равно или if Zero — если Ноль).

Синтаксис команды: LOOPE короткая_метка

LOOPZ короткая_метка

Логика работы команды:

СХ = Counter Short_Label: Выполнение тела цикла СХ = СХ — 1

if (СХ != 0 && ZF = 1) goto Short_Label

Все то, что говорилось для команды LOOP, справедливо и для команды LOOPE (LOOPZ), добавляется еще проверка флага ZF. Применяется данная команда в случае, если нужно досрочно выйти из цикла, как только находится ПЕРВЫЙ элемент, ОТЛИЧНЫЙ от заданной величины.

Команда LOOPNE (LOOPNZ)

•Команда LOOPNE (LOOPNZ) переход по счетчику и если НЕ равно

Данная команда тоже имеет два равнозначных мнемонических имени (if Not Equal — если НЕ равно или if Not Zero — если НЕ ноль). В отличие от предыдущей команды проверяется, сброшен ли флаг нуля ZF=0.

Как сделать цикл на ассемблере x86?

спросил

Изменено 7 лет, 1 месяц назад

Просмотрено 139 тысяч раз

Я написал код до сих пор:

 .code
основной
 Clrscr
  мов дч,10 ;строка 10
  mov dl,20 ;столбец 20
  вызвать Gotoxy ;найти курсор
  Промптфоринтегерс
    WriteString ; отображать строку
    ReadInt ;введите целое число
  Сумма массива
    WriteString ; отображать строку
    WriteInt ;отобразить целое число
DisplaySum ENDP
КОНЕЦ основной
 

Как заставить его повторять одни и те же шаги три раза, используя цикл, очищая экран после каждой итерации цикла?

  • петли
  • сборка
  • x86

4

 мов сх,3
циклический запуск:
   делать вещи
   dec cx ;Примечание: уменьшение cx и переход к результату
   jnz loopstart намного быстрее на Intel (и, возможно, на AMD, поскольку я не
                   ; проверено, может быть, 12 лет) вместо использования цикла loopstart
 

6

Еще один метод использует инструкцию LOOP:

 mov cx, 3
моя петля:
    ; Содержимое вашего цикла
    петля
 

Инструкция цикла автоматически уменьшает значение cx и выполняет переход только в том случае, если cx != 0. Существуют также варианты LOOPE и LOOPNE, если вы хотите сделать дополнительную проверку на преждевременное завершение цикла.

Если вы хотите изменить cx во время цикла, обязательно поместите его в стек перед содержимым цикла и извлеките его после:

 мов сх, 3
моя петля:
    нажать сх
    ; Содержимое вашего цикла
    поп сх
    петля
 

1

Использовать регистр CX для подсчета циклов

мов сх, 3
стартовый цикл:
   см сх, 0
   jz эндофлоп
   нажать сх
зацикленный:
   Вызов ClrScr
   поп сх
   дек сх
   джмп стартлуп
эндофлоп:
   ; Цикл завершен
   ; Делайте то, что когда-либо приходилось делать здесь
 

Это просто повторяется 3 раза, вызывая ClrScr , помещая регистр CX в стек, сравнивая с 0, переходя, если установлен ZeroFlag, затем переходя к эндофлоп . Обратите внимание, как содержимое CX помещается/извлекается из стека/из него для поддержания потока в цикле.

3

 .модель маленькая
.стек 100ч
.код
Основной процесс
Мов сх, 30; //это число управляет циклом 30 означает, что цикл будет
;возбудить 30 раз
Ioopfront:
Мов ах, 1
Интервал 21ч
лицевая петля;
 

этот код займет 30 символов

1

Вам нужно использовать условные команды jmp. Это не тот синтаксис, который вы используете; выглядит как MASM, но с использованием GAS вот пример кода, который я написал для вычисления gcd:

 gcd_alg:
    subl %ecx, %eax /* а = а - с */
    cmpl $0, %eax /* если a == 0 */
    je gcd_done /* перейти в конец */
    cmpl %ecx, %eax /* если a < c */
    jl gcd_preswap /* поменять местами и начать заново */
    jmp gcd_alg /* продолжайте вычитание */
 

В принципе, я сравниваю два регистра с помощью инструкции cmpl (сравнение длинное). Если оно меньше, инструкция JL (переход меньше) переходит к месту предварительной замены, в противном случае выполняется переход обратно к той же метке.

Что касается очистки экрана, это зависит от используемой вами системы.

1

Я искал тот же ответ и нашел эту информацию из вики полезной: Инструкции цикла

Инструкция цикла уменьшает значение ECX и переходит к адресу, указанному в arg, за исключением случаев, когда уменьшение значения ECX приводит к тому, что его значение становится равным нулю. Например:

 mov ecx, 5
 start_loop:
 ; код здесь будет выполнен 5 раз
 цикл start_loop
 

цикл не устанавливает никаких флагов.

loopx arg

Эти инструкции цикла уменьшают ECX и переходят на адрес, указанный arg, если их условие выполнено (то есть установлен определенный флаг), если только уменьшение ECX не привело к тому, что его значение стало равным нулю.

Источник: Сборка X86, поток управления

1

Зарегистрируйтесь или войдите в систему

Зарегистрируйтесь с помощью Google

Зарегистрироваться через Facebook

Зарегистрируйтесь, используя электронную почту и пароль

Опубликовать как гость

Электронная почта

Обязательно, но не отображается

Опубликовать как гость

Электронная почта

Требуется, но не отображается

Сборка

- Ассемблер Asm - Зацикливание цикла CX навсегда

Задавать вопрос

спросил

Изменено 9 лет, 7 месяцев назад

Просмотрено 3к раз

Я использую emu8086, www. emu8086.com - и имею следующий код:

 сегмент данных
пять экв 5
ПТО дб 5 дуп (1,2,3,4,5)
w2 дб 0
заканчивается
сегмент стека
дв 128 дуп(0)
заканчивается
сегмент кода
начинать:
мов топор, данные
мов дс, топор
мов эс, топор
;сумма
xor AX, AX
xor BX,BX
xor СХ, СХ
мов кл, пять
мов си,0
сумма:
добавить al,vet[si]
вкл. СИ
дек сх
сумма цикла
мов w2, ал
;конечная сумма
заканчивается
конец начало
 

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

по какой-то странной причине этого не происходит, программа вечно зацикливается.

в чем проблема с моим кодом? может кто-нибудь, пожалуйста, помогите мне?

  • циклы
  • сборка
  • бесконечный цикл

Инструкция 8086 LOOP уменьшает значение CX, а затем выполняет цикл, если CX не равен нулю. В вашем коде здесь:

 сумма:
добавить al,vet[si]
вкл. СИ
дек сх
сумма цикла
 

Сначала вы уменьшаете CX, а затем выполняете LOOP, который снова уменьшает его.

Оставить комментарий

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *