Stephen Landaas
Stephen Landaas

Reputation: 57

Infinite Loop Happening In MASM X86 Assembly Program

I'm currently in a computer organization and architecture class at my university, and we've been working with MASM a lot, and I've been toying around with some programs out of my own interest. Right now I'm writing a program that asks the user to input 10 numbers into an array, then it will calculate the largest number in the array. However, my issue is that unless the biggest number just so happens to be the very last number inputted, this program will crash and an infinite loop will form. I checked the contents of the ecx, and it appears that it goes... 10 9 8 7 6 5 4 3 2 1 -1 -2 -3, so it just skips 0. I'm sort of lost here, and not really sure what I'm doing wrong. Excuse my coding style, as I am still very new to this, but just trying to understand. Thanks!

INCLUDE Irvine32.inc

.data
    currentNum DWORD ?
    largestNum DWORD ?
    numbers DWORD 10 DUP(0)
    prompt BYTE "Enter a number:  ", 0
    message BYTE "The largest number is:  ", 0

.code
main PROC
    mov ecx, LENGTHOF numbers
    mov esi, OFFSET numbers
    mov eax, esi

    L1 :
        mov edx, OFFSET prompt
        call WriteString
        call ReadInt
        mov[esi], eax
        add esi, TYPE numbers
        loop L1

    mov ecx, LENGTHOF numbers
    mov esi, OFFSET numbers
    mov eax, [esi]
    mov largestNum, eax
    mov currentNum, eax

    L2:
        mov eax, [esi]
        mov currentNum, eax
        add esi, TYPE numbers
        cmp eax, largestNum
        ja setNewMax
        loop L2

    setNewMax:
        mov eax, currentNum
        mov largestNum, eax
        loop L2

    mov eax, largestNum
    mov edx, OFFSET message
    call WriteString
    call WriteDec
    call Crlf
    call Crlf

    exit

main ENDP


END main```

Upvotes: 0

Views: 413

Answers (1)

Tobias
Tobias

Reputation: 1371

The problem lies with the two loop instructions:

       ...
       ja    setNewMax
       loop  L2
setNewMax:
       mov   eax, currentNum
       mov   largestNum, eax
       loop  L2

The first loop (just before the setNewMax label here decrements ecx, discovers that it is zero and does not jump. Hence, it just continues executing the next instruction, i.e. mov eax, currentNum. Three instructions later, it encounters another loop instructions. It decreases ecx (which is now -1 and not zero) and hence takes the loop.

You could insert a jump out of this loop like so:

       ...
       ja    setNewMax
       loop  L2
       jmp   exitLoop
setNewMax:
       mov   eax, currentNum
       mov   largestNum, eax
       loop  L2
exitLoop:
       ...

Alternatively, you could go with just a simple loop instruction and write the second part of your loop like this:

       ...
       jna   endOfloop
setNewMax:             ; <- this label is not necessary anymore
       mov   eax, currentNum
       mov   largestNum, eax
endOfloop:
       loop  L2

Arguably, this code might be a bit easier to reason about because there is now only one loop instruction, and by inverting the logic of the ja jump, you even save an instruction :).

Upvotes: 2

Related Questions