Tasm - Assembly Loop

1.9k views Asked by At

I want to show "Hello World" once the user entered the correct password, but if the password is incorrect the program will prompt for Yes(Y)/No(N), if the user entered Yes(Y), the program will give 3 chances to the user to show the "Hello World" and if the user entered the No(N), the program will exit. My problem is that, every time I select Yes(Y), the program keeps looping, it just end if I entered No(N),

Here is the my code(I've skipped some parts)

   ...
    org 0100h
    .code

    mov ah, @data
    mov ds, ah


    mov cx, 3

    pool:
    dec cx
    jz full    ;jump if equal to zero seems of no effect, the loop is still counting

    dsply:
    <codes here are for requesting and comparing the password>

    ...
    ...
    ...
    cmp bl, al
    jne errr
    cmp cl, al
    jmp welc

    errr:
    mov ah, 9
    lea dx, pmpt   ; Displays whether the Yes(Y)/No(N)
    int 21h
    mov ah, 1
    mov cl, al
    int 21h

    cmp cl, 'Y'
    je dsply
    cmp cl, 'N'
    je endmain

    loop pool

    full:
    mov ah, 9
    lea dx, att   ;att will display You've Exceeded
    int 21h
    jmp endmain

    welc:
    mov ah, 9
    lea dx, hw  ; Displaying Hello World
    int 21h
    jmp endmain

    endmain:
    mov ah, 4ch
    int 21h
    end main

I don't know if this codes are right, I don't have the copy of my code right now, and also, I'm sorry if my code and explanation of the problem look stupid, but if anyone could please to help, it would be great, and more great if you could give me your another idea :)

1

There are 1 answers

5
Sep Roland On BEST ANSWER
errr:
  mov ah, 9
  lea dx, pmpt   ; Displays whether the Yes(Y)/No(N)
  int 21h
  mov ah, 1
  mov cl, al
  int 21h

You don't put your input in the CL register at all!
You need to move the mov cl, al instruction below the int 21h instruction.


mov ah, @data
mov ds, ah

I don't see how this can work. You should use a 16-bit register here.

mov ax, @data
mov ds, ax

cmp cl, al
jmp welc

Most probably this unconditional jmp is meant to become the conditional jne.


pool:
dec cx
jz full

You don't need this dec cx and jz full at the top of your loop. The loop pool instruction further below already does what is needed. (Observed by Sami Kuhmonen).

However...
since the loop instruction is slow (Observed by Peter Cordes) you should avoid using it and replace it with code similar to the redundant instructions you had at the top of your loop.
But wait, there's one more thing wrong! Your loop uses the CX register as its iteration counter, but at the same time the code within the body of the loop uses this same CX register for other purposes. This inevitably leads to problems! You need to be careful with how you use these registers.

This is a solution:

    mov     cx, 3
pool:
    push    cx      ;(1) Save the iteration counter on the stack
dsply:
    ...
    <codes here are for requesting and comparing the password>
    ...
    pop     cx      ;(1) Restore the iteration counter
    dec     cx
    jnz     pool
full:
    mov     ah, 9

cmp cl, 'Y'
je dsply
cmp cl, 'N'
je endmain

Once you got your program working, you'll have a potential problem here. What will happen when the user types in a small "y" or a small "n" ?
The program won't recognize it!

It would be best to capitalize the input:

and cl, 11011111b
cmp cl, 'Y'
je  dsply
cmp cl, 'N'
je  endmain

Please use the DOS API as it is intended to be used. The TerminateWithReturnCode function does expect a return code in the AL register. It's a real small effort to write:

mov  ax, 4C00h  ;Function number in AH, Return code in AL
int  21h