I have created this code, but now I need the create new prgram that repeats the same steps three times, using loop. Clear the screen after each loop iteration. ???

integer_count = 3

promptuser byte "Enter a two integers: ", 0
sumOf byte "The sum of the integers is: ", 0
 array dword integer_count dup (?)
 main proc

        call clrscr
		mov dh, 15
		mov dl, 25
		call gotoxy
		call crlf
	    mov  esi, offset array
        mov  ecx, integer_count
        call promptforintegers
        call arraysum
        call displaysum
		call dumpregs
main ENDP

promptforintegers proc uses ecx edx esi

;Prompts the user for an arbitrary number of integers and inserts the 
;integers into an array.
;Receives: ESI points to the array, ECX = array size
;Returns: nothing
			mov edx, offset promptuser		; "Enter a signed integer"
		L1: call	writestring			; display string
			call	readint				; read integer into eax
			call	crlf				; go to next output line
			mov [esi] ,eax				; store in array
			add esi, type dword			; next integer
			Loop L1
promptforintegers endp

arraysum proc uses esi ecx

;Calculates the sum of an array of 32-bit integers.
;Receives: ESI prints to the array, ECX = number
;of array elements
;Returns: EAX = sum of the array elements

				mov eax, 0				; set the sum to zero
		L1:		add  eax, [esi]			; add each integer to sum
				add esi, type dword		; point to next integer
				call dumpregs
				Loop L1					; repeat for array size
				ret						; sum is in eax
	arraysum endp

displaysum proc uses edx

;Displays the sum on the screen
;Receives: eax = the sum
;Returns: nothing

		mov		edx, offset sumOf		; "The sum of the ..."
		call	writestring
		call	writeint				; display eax
		call	crlf
displaysum endp
end main
5 Years
Discussion Span
Last Post by sbesch

I think what you want to do is loop on lines 19-22, so, put a label at line19 and a loop after line 22:

     call promptforintegers
     call arraysum
     call displaysum
     call dumpregs
   loop LoopHere

You can also use one of the conditional loop instructions to test for the zero flag, etc.The loop instruction always decrements ECX for you and will loop till the count expires, or in the case of loopz and loopnz, until the NZ or Z condition is met, which ever occurs first.

Here's another suggestion. Don't load registers with a zero immediate operand. use xor instead. Thus, where you have:

MOV EAX,0 //or other register

use this instead:

XOR EAX,EAX //or other register

It is faster and more compact and completely operand size independent.

Edited by sbesch: Typo


I just noticed another potential problem with your code. You are using ECX in a way that may give you problems down the road. To be sure,"USES ECX" in the proc directive will push ECX on the stack and pop it on return, preserving its value. The problem is that you then have to jump through some hoops to use ECX as a counter in the main loop (as I suggested above), since it's value for the downstream calls will change after every pass of the outer loop. Even if the value for the procedure calls and the outer loop will always be the same (3) I would not recommend this method. Either pass a count into your subroutines (Put it in EAX or on the stack), then set ECX explicitly in the subroutines - or hard code it, especially if the array sizes are hard coded. This keeps the count for the outer loop independent from the loops in the subroutine calls. You still of course need to save ECX on entering the routine (either with USES or an explicit PUSH/POP pair), but the resulting code is cleaner and more bulletproof.

This article has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.