How to make a loop in x86 assembly language?
Solution 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
Solution 2
Yet another method is using the LOOP instruction:
mov cx, 3
myloop:
; Your loop content
loop myloop
The loop instruction automatically decrements cx, and only jumps if cx != 0. There are also LOOPE, and LOOPNE variants, if you want to do some additional check for your loop to break out early.
If you want to modify cx during your loop, make sure to push it onto the stack before the loop content, and pop it off after:
mov cx, 3
myloop:
push cx
; Your loop content
pop cx
loop myloop
Solution 3
Use the CX register to count the loops
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
This simply loops around 3 times calling ClrScr
, pushing the CX register onto the stack, comparing to 0, jumping if ZeroFlag is set then jump to endofloop
. Notice how the contents of CX is pushed/popped on/off the stack to maintain the flow of the loop.
Solution 4
.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;
this cod will take 30 character
Admin
Updated on July 26, 2022Comments
-
Admin almost 2 years
I have written the code so far as:
.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
How do I get it to repeat the same steps three times using a loop, clearing the screen after each loop iteration?
-
PA. over 14 yearsyou may use
loop loopstart
instead ofdec cx
andjnz loopstart
as long asdo stuff
preserves the cx register -
PA. over 14 yearsa couple of optimizations: (1)you may use
jcxz label
instead ofcmp cx,0
andjz label
. (2) you may useloop label
instead ofdec cx
andjnz label
-
Jeff B over 14 years@PA: Preserving cx is necessary even if you don't use
loop
. -
Jeff B over 14 years@PA: Depending on your processor,
jcxz label
andcmp/jz
are equivalent. Recent x86 processor use macro-fusion to combine cmp/jmp instructions into a single cycle instruction, essentially replicatingjcxz
behavior on the fly. -
Vincenzo Pii over 12 yearsThis is absolutely correct since the question is about looping three times. However, the question title is much more generic and I think it may be useful to add that, if cx value came from a variable and not from a constant, a JBE zero instruction, to jump to the loopend before entering the loop, would be needed.
-
Anderson Green about 11 yearsWhich variable or register is being used as the loop counter here?
-
kirbyfan64sos over 10 years@AndersonGreen:
cx
. -
Peter Cordes about 8 years
loop
is slow, and using it is not a good habit. If you need ecx for something inside your loop (e.g. a shift instruction), then just use a different register for the loop counter. Having a push/pop in the loop-counter dependency chain is just silly. Usually loops need some kind of induction variable, so just test that. e.g. increment a pointer by 4 each time through the loop, andcmp / jb
against an end pointer as the loop condition. -
Peter Cordes about 8 yearsThis loop is incredibly inefficient. If a loop might run zero times, then test the counter outside the loop. Then use a conditional branch at the end of the loop. And use a register that you won't need to push/pop as your loop variable. (e.g. a call-preserved register like (e/r)bx or (e)si if there are function calls in your loop.). And Jeff B is right:
cmp/jz
ordec/jz
is cheaper thanjcxz
on modern CPUs like Intel Haswell. See agner.org/optimize -
Peter Cordes about 8 yearsWorks, but slower than
dec/jnz
. -
Peter Cordes about 8 yearsIf you're making a function call inside the loop, use a different register for your counter:
bx
is preserved across function calls in 32 and 64bit ABIs, and I assume also in 16bit ABIs. And yes,loop
is slow. Don't use it, and don't fall into the trap of thinking that you need a separate loop counter if you can instead just test a pointer or something that you already need in the loop. (e.g.cmp si,bx / jb
at the bottom.) -
Michael about 8 yearsWhat does this add that wasn't already explained in the other answers posted years ago?