web-dev-qa-db-fra.com

Comment faire une boucle en langage assembleur x86?

J'ai écrit le code jusqu'à présent:

.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

Comment puis-je le faire répéter les mêmes étapes trois fois en utilisant une boucle, en effaçant l'écran après chaque itération de la boucle?

15
user267288
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
19
Arthur Kalliokoski

Une autre méthode utilise l’instruction LOOP:

mov  cx, 3

myloop:
    ; Your loop content

    loop myloop

L'instruction de boucle décrémente automatiquement cx et ne saute que si cx! = 0. Il existe également des variantes LOOPE et LOOPNE si vous souhaitez effectuer une vérification supplémentaire pour que votre boucle se déclenche plus tôt.

Si vous souhaitez modifier cx pendant votre boucle, assurez-vous de le placer dans la pile avant le contenu de la boucle et de le supprimer après:

mov  cx, 3

myloop:
    Push cx
    ; Your loop content
    pop  cx

    loop myloop
11
Jeff B

Utilisez le registre CX pour compter les boucles

 mov cx, 3 
 startloop: 
 cmp cx, 0 
 jz endofloop 
 Appuyez sur cx 
 Loopy: 
 Appelez ClrScr 
 pop cx 
 dec cx 
 jmp startloop 
 endofloop: 
 ; Boucle terminée 
 ; Faites ce que vous devez faire ici 

Cela boucle simplement environ 3 fois en appelant ClrScr, en poussant le registre CX sur la pile, en comparant à 0, sautant si ZeroFlag est défini puis sautant à endofloop. Remarquez comment le contenu de CX est poussé/sauté sur la pile pour maintenir le flux de la boucle.

2
t0mm13b
.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; 

cette morue aura 30 caractères 

1
rafeef

Je cherchais la même réponse et trouvais cette information utile sur le wiki: Instructions pour la boucle

L'instruction de boucle décrémente ECX et saute à l'adresse spécifiée par arg, à moins que la décrémentation d'ECX entraîne sa valeur à zéro. Par exemple:

 mov ecx, 5
 start_loop:
 ; the code here would be executed 5 times
 loop start_loop

la boucle ne définit aucun indicateur.

_ loopx arg

Ces instructions de boucle décrémentent ECX et sautent à l'adresse spécifiée par arg si leur condition est remplie (c'est-à-dire si un indicateur spécifique est défini), à moins que la décrémentation d'ECX ne provoque sa valeur à zéro.

  • _ {boucle) boucle si égale

  • loopne boucle si différente

  • loopnz boucle si non nulle

  • loopz boucle si zéro

Source: Assemblage X86, flux de contrôle

0
Pranav Singh

Vous devez utiliser des commandes jmp conditionnelles. Ce n'est pas la même syntaxe que vous utilisez; ressemble à MASM, mais en utilisant GAS, voici un exemple tiré du code que j'ai écrit pour calculer 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 */

En gros, je compare deux registres à l’instruction cmpl (comparer longtemps). Si ce n'est pas le cas, l'instruction JL (sauter moins) saute à l'emplacement de pré-swap, sinon elle reviendra à la même étiquette.

Quant à l’effacement de l’écran, cela dépend du système que vous utilisez.

0
user257111