2

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 :)

ZachB
  • 13,051
  • 4
  • 61
  • 89
stevenjake
  • 23
  • 6

1 Answers1

2
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
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • Please don't suggest that people start using `loop`. [It's slow on modern CPUs](https://stackoverflow.com/questions/35742570/why-is-the-loop-instruction-slow-couldnt-intel-have-implemented-it-efficiently), and it's probably better to learn the more general way of making loops with conditional branches. I've seen way too much 16-bit code that just blindly used `loop` when it would be more convenient to use something else as the loop condition and not tie up `cx`. Clearly beginners fall into the trap of thinking `loop` is the only way to loop. – Peter Cordes Aug 27 '17 at 22:09
  • Hi Sep, Thanks for your suggestions in my code, it really is grateful you've told what's wrong with it, xD, I'll keep in touch with your words, though I haven't edited and tested yet your revisions, you seems so Great!, Thank You So Much!, :) – stevenjake Aug 28 '17 at 13:48
  • @PeterCordes Thanks for the advice on the `loop` instruction. I've edited my answer with credits. I should probably say sorry for next time as I am so accustomed to using this instruction... – Sep Roland Sep 10 '17 at 21:46
  • @user8141558 Please read my revised answer. Perhaps the new info herein will also answer the follow up question(s) that you've asked! – Sep Roland Sep 10 '17 at 21:50
  • Cool, thanks. I hadn't realized that the OP was using `loop`. I saw `dec cx / jz` in the code, then realized it was a mess so I lost interest and skipped to the answer to see what you had to say, since you'd already done the work of figuring out what the question was asking. I thought you had introduced a `loop` instead of a `jmp` back to `dec/jz` or something. Telling people to replace `loop` in every 16-bit answer about unrelated questions would get boring, so it only really bothers me if people use `loop` where the OP didn't already. (But in this case the question is about the loop). – Peter Cordes Sep 10 '17 at 21:57