Tasm - 装配循环
Tasm - Assembly Loop
我想在用户输入正确的密码后显示"Hello World",但如果密码不正确,程序将提示是(Y)/否(N),如果用户输入是(Y ),程序会给用户 3 次显示 "Hello World" 的机会,如果用户输入 No(N),程序将退出。
我的问题是,每次我 select Yes(Y),程序一直循环,如果我输入 No(N),它就会结束,
这是我的代码(我跳过了一些部分)
...
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
很可能这个 unconditional jmp
是为了成为 conditional jne
.
pool:
dec cx
jz full
您不需要在循环顶部使用 dec cx
和 jz full
。下面的 loop pool
指令已经完成了所需的工作。 (被 Sami Kuhmonen 观察到)。
然而...
因为 the loop
instruction is slow (Observed by 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
寄存器中的 return 代码。写起来真是不费吹灰之力:
mov ax, 4C00h ;Function number in AH, Return code in AL
int 21h
我想在用户输入正确的密码后显示"Hello World",但如果密码不正确,程序将提示是(Y)/否(N),如果用户输入是(Y ),程序会给用户 3 次显示 "Hello World" 的机会,如果用户输入 No(N),程序将退出。 我的问题是,每次我 select Yes(Y),程序一直循环,如果我输入 No(N),它就会结束,
这是我的代码(我跳过了一些部分)
...
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
很可能这个 unconditional jmp
是为了成为 conditional jne
.
pool: dec cx jz full
您不需要在循环顶部使用 dec cx
和 jz full
。下面的 loop pool
指令已经完成了所需的工作。 (被 Sami Kuhmonen 观察到)。
然而...
因为 the loop
instruction is slow (Observed by 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
寄存器中的 return 代码。写起来真是不费吹灰之力:
mov ax, 4C00h ;Function number in AH, Return code in AL
int 21h