Tasm - Assembly Loop
一旦用户输入了正确的密码,我想显示“Hello World”,但是如果密码不正确,程序会提示输入Yes(Y)/ No(N),如果用户输入Yes Y),程序将给用户三次机会显示“Hello World”,如果用户输入了No(N),程序将退出。 我的问题是,每次我选择是(Y),该程序保持循环,其刚刚结束,如果我进入否(N),Tasm - Assembly Loop
这里是我的代码(我已经跳过某些部分)
...
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
我不知道这段代码是否正确,我现在没有我的代码的副本,而且,如果我的代码和问题的解释看起来很愚蠢,我很抱歉,但如果有人可以请帮助,这将是伟大的,更伟大的,如果你能给我你的另一种想法:)
errr: mov ah, 9 lea dx, pmpt ; Displays whether the Yes(Y)/No(N) int 21h mov ah, 1 mov cl, al int 21h
根本没有在CL
寄存器中输入!
您需要将mov cl, al
指令移动到int 21h
指令之下。
mov ah, @data mov ds, ah
我不明白这是如何工作的。你应该在这里使用一个16位寄存器。
mov ax, @data
mov ds, ax
cmp cl, al jmp welc
最大的可能是这无条件jmp
是为了成为条件jne
。
pool: dec cx jz full
你不需要这个dec cx
和jz full
在你的循环顶部。下面的loop pool
指令已经完成了所需的工作。 (由Sami Kuhmonen观察)。
但是...
因为the loop
instruction is slow(由Peter Cordes观察),你应该避免使用它,类似于您在上环上方的冗余指令代码替换它。
但是等等,还有一件事情是错误的!您的循环使用CX
寄存器作为其迭代计数器,但同时循环体内的代码使用此相同的CX
寄存器用于其他目的。这不可避免地会导致问题!你需要注意你如何使用这些寄存器。
这是一个解决方案:
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
一旦你得到了你的程序的工作,你会在这里有一个潜在的问题。当用户键入一个小的“y”或一个小的“n”时会发生什么?
程序不会识别它!
这将是最好的资本输入:
and cl, 11011111b
cmp cl, 'Y'
je dsply
cmp cl, 'N'
je endmain
请使用DOS API,因为它打算使用。函数TerminateWithReturnCode函数确实会在AL
寄存器中返回代码。这是一个真正的小型努力,写:
mov ax, 4C00h ;Function number in AH, Return code in AL
int 21h
请不要建议人们开始使用'loop'。 [它在现代CPU上很慢](https://*.com/questions/35742570/why-is-the-loop-instruction-slow-couldnt-intel-have-implemented-it-efficiently),这可能更好学习使用条件分支进行循环的更一般的方法。我已经看到了太多的16位代码,只是盲目地使用'loop'时,如果使用别的东西作为循环条件并且不绑定'cx',会更方便。很明显,初学者陷入了思考'循环'是循环的唯一途径。 –
嗨,九月,感谢您在我的代码中的建议,它真的很感激您已经告诉它有什么问题,xD,我会与您的话保持联系,虽然我还没有编辑和测试过您的修订版本,但您看起来太好了,谢谢你这么多!:) – user8141558
@PeterCordes感谢您对'loop'指令的建议。我用学分编辑了我的答案。我应该在下次对不起,因为我习惯于使用这个指令... –
你不应该发布代码,甚至可能不是实际的代码。但只要想想你在代码中对CX寄存器做了什么,那就应该告诉你为什么它不会为零。也不应该有理由使用'loop',然后手动'dec cx'。 –
您是否尝试过使用调试器单步调试? –
@SamiKuhmonen我的错误,对不起,但仍然,谢谢你!您的建议非常感谢 – user8141558