I am trying to figure out the way to use the nested loop in a proper way but so far i am failed,

The loop run to infinity when i run the program which i definitely don't want to do,

here is my code,

 .MODEL SMALL
 .STACK 100H

 .DATA
    var1  DB  '*$'

 .CODE
   MAIN PROC

     MOV AX, @DATA                ; initialize DS
     MOV DS, AX
     MOV CX,10   

     LEA DX, var1             ; load the string
     MOV AH, 9                                           


        L2:
            L1:
                INT    21H
            Loop L1

            DEC CX

        JNZ L2

     MOV AH, 4CH                  ; return control to DOS
     INT 21H

   MAIN ENDP
 END MAIN

Where am i doing wrong ?
I am just trying to print * in the pyramid form

Recommended Answers

All 7 Replies

Here's pseudocode for what you're doing:

cx = 10

while cx <> 0
    while cx <> 0
        int 21h
        dec cx
    loop

    dec cx
loop

So cx starts out as 10 and gets decremented to 0 by the inner loop. Then the outer loop decrements it again to make it negative and tests it against zero. cx is obviously not zero at this point, so the outer loop repeats. cx is still not zero, so the inner loop repeats.

Now you're looking at an underflow situation, where the inner loop will repeat until cx underflows, and hopefully wraps back around to 0. But ultimately this code represents a bug and should be fixed.

My guess would be that you're trying to use cx to represent two things (rows and columns) but the two nested loops are stepping on each other. You can get around that by saving and restoring cx around the inner loop:

; Print a right triangle

mov cx, 10     ; Decreasing number of rows remaining
mov ax, 1      ; Increasing number of asterisks per row

rows:
    mov dx, cx ; Save cx for later
    mov cx, ax ; Use ax's value for the inner loop counter

    cols:
        int 21h
    loop cols

    mov cx, dx ; Restore cx for the outer loop
    inc ax     ; Add an asterisk for the next row
loop rows

Another alternative would be to eschew the loop instruction and do it manually with two registers instead of one.

Thank you i've understand my mistake and your code too, when the loop starts the value '10' will be stored in 'DX' and the value '1' will be moved to 'Cx' for the inner loop counter, hence the inner loop will run once.
After coming out of the loop the value of 'Ax' will be incremented by one, this process will execute 10 times....

P.S: your code doesnt work, The HTVDM CPU has encountered an illegal instruction. CS:8bd1 IP:8e22 OP:ff ff eb 05 ea
Choose 'Close' to terminate appliation.
I am getting this error when executing the code.

I am getting this error when executing the code.

I guess you'll have to use the same logic and write working code then. ;)

Any specific reason as I guess this is due to the version of DOS ?

Any specific reason as I guess this is due to the version of DOS ?

The most likely reason is that I haven't worked with assembly in several years and while the logic was sound, the actual code is subtly (or blatantly) wrong somewhere.

Problem solved :) your post really helped :)

Xufan - It would be nice if you could tell the forum exactly why you were getting an illegal instruction. There is clearly nothing in deceptikon's code snippet that would cause this - it wouldn't even compile if there were. I also doubt that it had to do with DOS version, etc. For all the world, it looks like the program was allowed to somehow run off into random bytes in the code segment. This is usually due to a missing or malformed JMP instruction, most commonly an indirect JMP where the register containing the address was either not set or set incorrectly. The other possibility that comes to mind is executing a RET instruction after corrupting the stack. If you know what the problem was, tell us so that others can avoid the same error.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.