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

Я написал код так:

.code

main
 Clrscr

  mov dh,10            ;row 10

  mov dl,20            ;column 20

  call Gotoxy          ;locate cursor

  PromptForIntegers  

    WriteString       ;display string
    ReadInt           ;input integer
  ArraySum

    WriteString       ;display string
    WriteInt          ;display integer

DisplaySum  ENDP

END main

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

Ответы

Ответ 1

mov cx,3

loopstart:
   do stuff
   dec cx          ;Note:  decrementing cx and jumping on result is
   jnz loopstart   ;much faster on Intel (and possibly AMD as I haven't
                   ;tested in maybe 12 years) rather than using loop loopstart

Ответ 2

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

mov  cx, 3

myloop:
    ; Your loop content

    loop myloop

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

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

mov  cx, 3

myloop:
    push cx
    ; Your loop content
    pop  cx

    loop myloop

Ответ 3

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

mov cx, 3
startloop:
   cmp cx, 0
   jz endofloop
   push cx
loopy:
   Call ClrScr
   pop cx
   dec cx
   jmp startloop
endofloop:
   ; Loop ended
   ; Do what ever you have to do here

Это просто трижды вызывает вызов ClrScr, нажав регистр CX на стек, сравнивая с 0, прыгая, если установлен ZeroFlag, затем перейдите к endofloop. Обратите внимание, как содержимое CX выталкивается/вынимается из стека, чтобы поддерживать поток цикла.

Ответ 4

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

gcd_alg:
    subl    %ecx, %eax      /* a = a - c */
    cmpl    $0, %eax        /* if a == 0 */
    je      gcd_done        /* jump to end */
    cmpl    %ecx, %eax      /* if a < c */
    jl      gcd_preswap     /* swap and start over */
    jmp     gcd_alg         /* keep subtracting */

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

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

Ответ 5

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

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

 mov ecx, 5
 start_loop:
 ; the code here would be executed 5 times
 loop start_loop
Цикл

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

loopx arg

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

  • цикл loope, если он равен

  • loopne loop, если не равно

  • loopnz loop, если не ноль

  • loopz loop, если нуль

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

Ответ 6

.model small
.stack 100h
.code 
Main proc
Mov cx , 30 ; //that number control the loop 30 means the loop will 
;excite 30 time 
Ioopfront:
Mov ah , 1
Int 21h 
Loop loopfront; 

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