UMBC Repetition Previous | Next


Repetition

A loop is a necessary software control structure (used for repetition) and is used a lot! Loops in C come as for, while, and do while. All loop, both C and assembly language, have three parts, initialization, modification and test for termination.

Flowchart Of A Loop

The only different between a while and a do while loop is the while loops tests for continuation at the top of the loop and the do while loop test for continuation as the bottom of the loop. Thus, while loops may not execute at all, but a do while loop is going to execute at least one time.

A simple loop is the for statement:

C version

  for ( n = 10; n > 0; n-- )
    /* do something */  ;

A Crude Version

In assembly language, we control most loops using the CX register:

         mov  cx, n   ; Initialize
theLoop: 

                      ; do something 

         dec  cx      ; Modification
         jnz  theLoop ; Test for termination -- can also use jg

An Improvement

         mov  cx, n   ; Initialize
theLoop:

                      ; do something 

         dec  cx      ; Modification
         jcxz theLoop ; Test for termination 

Even Better

         mov  cx, n   ; Initialize
theLoop: 

                      ; do something  

         loop theLoop ; Modification and test for termination

What about .... ?

What happens if the value is n is 0? 216 is 65,536, and that is how many times the loop will execute.

What if I want to count up instead of down? You must use the first version and use a different conditional jump and inc instead of dec.

What if I want to adjust the count by a value different that 1? Use add or sub, as appropriate.

Can I do anything in assembly language that I can do with a for statement in C? Of course.

What about while and until in C, can I do them? Yes, just make sure to put the compare and jump in the correct location.

Example program

C Version

#include <stdio.h>

int main ( void )
{
  int i;

  /* simple for loop */
  printf( "For Loop 1\n" );
  for ( i = 10; i > 0; i-- )
    {
      printf( " i = %d\n", i );
    }

  /* simple reverse for loop */
  printf( "For Loop 2\n" );
  for ( i = 1; i <=  10; i++ )
    {
      printf( " i = %d\n", i );
    }

  /* by twos for loop */
  printf( "For Loop 3\n" );
  for ( i = 1; i <= 10; i+=2 )
    {
      printf( " i = %d\n", i );
    }

  return 0;
}

Assembly Language Version

section .data
str1	db	'For Loop 1',10,0
str2	db	'For Loop 2',10,0
str3	db	'For Loop 3',10,0
outstr	db	' i = %d',10,0

section .bss
i	resd	1

section .text
    global main                       ;must be declared for linker (ld)

main:                                 ;tell linker entry point
extern	printf

	push	str1
	call	printf
	add	esp, 4
	
	mov	ecx, 10
loop1:	
	push	ecx		      ; printf does not preserve the ecx register
				      ; so I must.
	push	ecx
	mov	[i], ecx              ; The C code changes the value of i with
                                      ; each step.  I will also
	push	outstr
	call	printf
	add	esp, 8
	pop	ecx		      ; return ecx
	loop	loop1                 ; decrement ecx and loop until zero.

	push	str2
	call	printf
	add	esp, 4
	
	mov	ecx, 10
	mov	dword [i], 1
loop2:	
	push	ecx		      ; printf does not preserve the ecx register
				      ; so I must.
	push	dword [i]
	push	outstr
	call	printf
	add	esp, 8
	pop	ecx
	inc	dword [i]
	loop	loop2                 ; decrement ecx and loop until zero.

	push	str3
	call	printf
	add	esp, 4
	
	mov	ecx, 10
	mov	dword [i], 1
loop3:	
	push	ecx		      ; printf does not preserve the ecx register
				      ; so I must.
	push	dword [i]
	push	outstr
	call	printf
	add	esp, 8
	pop	ecx
	inc	dword [i]	      ; or sub dword [i], 2
	inc	dword [i]
	dec	ecx
	loop	loop3                 ; decrement ecx and loop until zero.


;; The final part of the program must be a call to the operating system to exit
;;; the program.
        mov     ebx,0   ;successful termination of program
        mov     eax,1   ;system call number (sys_exit)
        int     0x80    ;call kernel



Previous | Next

©2004, Gary L. Burt