Как сделать цикл на языке ассемблера x86? - PullRequest
16 голосов
/ 05 февраля 2010

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

.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

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

Ответы [ 6 ]

19 голосов
/ 05 февраля 2010
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
11 голосов
/ 05 февраля 2010

Еще один метод использует инструкцию 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
2 голосов
/ 05 февраля 2010

Использование регистра 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

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

1 голос
/ 06 апреля 2016
.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 символов

0 голосов
/ 04 марта 2013

Я искал тот же ответ и нашел эту информацию из вики полезной: 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 его значение не станет равным нулю.

  • петля петля, если она равна

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

  • loopnz цикл, если не ноль

  • loopz цикл, если ноль

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

0 голосов
/ 05 февраля 2010

Вам нужно использовать условные команды 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 (без перехода) переходит в положение предварительной замены, в противном случае она возвращается к той же метке.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...