loopsassemblymasmemu8086triangle

Experiencing Infinite Loop with Right Triangle Program in MASM Assembly Language


I'm currently trying to make a program in MASM assembly language that will print out a series of right triangles based on an integer value that the user inputs. For example, if the user input is 3 then the program will output:

*

*  * 

*  *  *

-

*  *  *

*  *

*

-

      *

   *  *

*  *  * 

-

*  *  *

   *  *

      *

I have figured out all of the triangles except the third one. I'm experiencing an infinite loop with spaces1 under triangle 3. The program will print out the triangle correctly up until it reaches one less than what the user integer value is, and then it loops spaces for infinity. I've been working on this for a while and I'm not sure how to fix this error. Here's my code:

org 100h      

.model small

.stack 16

.data
; question the user is asked
input db "Enter the size for the triangles between 3 and 9, or 0 to quit $"
size dw ?

.code

main proc
    mov AX, @data                           ; move location of data segment into AX
    mov DS, AX                              ; points ds register at data segment
    
    prompt: 
        mov AH, 09h                         ; opcode to print string
        lea DX, input                       ; string to print out
        int 21h
        
        mov AH, 01h                         ; opcode to read in single char
        int 21h
        cmp AL, '0'                         ; check to see if user wants to quit
        je exit
        
        sub AL, '0'                         ; convert user input to literal value
        mov AH, 0                           ; blank out top half of AX
        mov size, AX                        ; make copy of user input as literal value     
        
        mov CX, AX
        mov BX, 1                           ; sets up BX register for star counter loop    
        
        call crlf                               
        
    ; First Triangle
    lines1: 
        push CX                             ; store the outer (lines) loop
        mov CX, BX                          ; the number of stars to print out
        
        stars1: 
            mov AH, 02h                     ; opcode to print string
            mov DL, '*'                     ; char to print out
            int 21h   
            
        loop stars1                         ; end loop
        
        call crlf
        inc BX                              ; increment BX (stars)
        pop CX                              ; recover value from CX for the outer lines loop
        
    loop lines1                             ; end loop
       
    call crlf
    mov CX, size                            ; reload CX with copy of size for next triangle
    mov BX, 1     
    
    ; Second Triangle   
    lines2:
        push CX                             ; store the outer (lines) loop    
        
        stars2: 
            mov AH, 02h                     ; opcode to print single char
            mov DL, '*'                     ; char to print out
            int 21h              
            
        loop stars2                         ; end loop
        
        call crlf                   
        pop CX                              ; recover value for outer loop
        
    loop lines2                             ; end loop   
    
    call crlf                               ; call crlf proc
    mov CX, size                            ; reload CX with copy of size for next triangle
    mov BX, 1                               ; set up BX for star loop
    
    ; Third Triangle
    lines3:
        push CX                             ; Store the outer loop counter
        mov CX, size                        ; Calculate spaces needed
        sub CX, BX                          ; Adjust CX for the number of spaces

        spaces1:
            mov AH, 02h                     ; Opcode to print single char
            mov DL, ' '                     ; Print a space
            int 21h
        loop spaces1                        ; End loop for spaces

        mov CX, BX                          ; Set number of stars for this line
        stars3:
            mov AH, 02h                     ; Opcode to print single char
            mov DL, '*'                     ; Print a star
            int 21h
        loop stars3                         ; End loop for stars

        call crlf                           ; Move to the next line
        inc BX                              ; Increment the number of stars for the next line
        pop CX                              ; Restore outer loop counter

    loop lines3                             ; End outer loop

    call crlf                               ; call crlf proc
    mov CX, size                            ; set up CX for fourth triangle
    mov BX, 1                               
    
    ; Fourth Triangle
    lines4:
        push CX                             ; store copy of CX for outer loop       
        mov CX, BX                          ; set up number of spaces for spaces loop
        
        spaces2:
            mov AH, 02h                     ; opcode to print char
            mov DL, ' '                     ; char to print out
            int 21h
        loop spaces2                        ; end loop
        
        pop CX                              ; recover CX for stars loop
        push CX                             ; for outer lines loop
        
        stars4:   
            mov AH, 02h                     ; opcode to print char
            mov DL, '*'                     ; char to print out
            int 21h   
        
        loop stars4                         ; end loop   
        
        call crlf
        
        inc BX                              ; increment BX for next line 
        pop CX                              ; recover value for outer lines loop
    
    loop lines4
    
    call crlf                               ; call crlf proc
    mov CX, size                            ; set up CX for fourth triangle
    mov BX, 1   
    
    exit:
        mov AX, 4C00h
        int 21h
                                                               
main endp

crlf proc
    mov AH, 02h                             ; opcode to print single char
    mov DL, 13                              ; ASCII carriage return
    int 21h
    mov DL, 10                              ; ASCII line feed
    int 21h
    ret

crlf endp
end main

Here's a screenshot of the issue. In the program it's looping between lines 92 and 95 in spaces1 enter image description here Could someone point me in the right direction? Thanks! :)


Solution

  • Both the 3rd and the 4th triangles have a line where no space has to be inserted. You need to add a suitable by-pass of the spaces1 and spaces2 loops.

      mov CX, size
      mov BX, 1
    ; Third Triangle
    lines3:
      push CX
      mov  CX, size
      sub  CX, BX       ; If this subtraction produces 0 then
      jz   SkipSpaces1  ; this jumps over (so skips) the spaces1 loop
    spaces1:
      mov  AH, 02h
      mov  DL, ' '
      int  21h
      loop spaces1
    SkipSpaces1:
      mov  CX, BX
    

    In case of the 4th triangle, set up BX=0 because there's no space on the very first line:

      mov CX, size
      mov BX, 0
    ; Fourth Triangle
    lines4:
      push CX
      mov  CX, BX       ; If this loads CX with 0, then
      JCXZ SkipSpaces2  ; this jumps over (so skips) the spaces2 loop
    spaces2:
      mov  AH, 02h
      mov  DL, ' '
      int  21h
      loop spaces2
    SkipSpaces2:
      pop CX