Assembly 装配循环错误
我正在尝试在汇编(masm)中编写一个程序,该程序将接受用户输入,并且该程序将输出一个从0到该输入的计数(介于0到99之间)。我遇到的错误是,无论我输入什么数字,程序都会循环到看似随机的数字,然后终止。任何帮助都将不胜感激Assembly 装配循环错误,assembly,masm,Assembly,Masm,我正在尝试在汇编(masm)中编写一个程序,该程序将接受用户输入,并且该程序将输出一个从0到该输入的计数(介于0到99之间)。我遇到的错误是,无论我输入什么数字,程序都会循环到看似随机的数字,然后终止。任何帮助都将不胜感激 cseg segment 'code' assume cs:cseg, ds:cseg, ss:cseg, es:cseg org 100h start: mov ah, 09 mov dx, offset Intro int 21
cseg segment 'code'
assume cs:cseg, ds:cseg, ss:cseg, es:cseg
org 100h
start:
mov ah, 09
mov dx, offset Intro
int 21h
mov ah, 01
int 21h
sub al, 30h
mov bl,0Ah
mul bl
mov bl, al
mov ah, 01
int 21h
sub al, 30h
add bl, al
mov cl, bl
jmp again
again:
mov ah, 09
mov dx, offset Hello
int 21h
mov dx, offset msg1
int 21h
mov dx, offset msg
int 21h
inc byte ptr msg
mov al, msg
cmp al, 3ah
jg reset
loopne again
reset:mov byte ptr msg, 30h
inc byte ptr msg1
cmp cx, 0
jg again
jmp done
done:
mov ah, 4ch
int 21h
org 200h
Intro db "Please input how many times you would like the loop to run." , 20h, 20h, "$"
Hello db "hello world" , 20h, 20h, "$"
msg db 30h, 13, 10, "$"
msg1 db 30h, "$"
cseg ends
end start
两个问题:
bl
分配给cl
,而不清除ch
部分,最好使用类似movzx-cx,bl
cmp cx,0之前添加dec cx
建议:无需再次使用
jmp
或jmp done
指令loopne
使用CX
寄存器,只需初始化CL
寄存器,该寄存器是CX
的低位字节。如果坚持使用loopne
,请清除CH
,这是CX
的高位字节
当然,解决方案要简单得多。保持修改文本计数器的逻辑与主循环的逻辑无关。最糟糕的情况是,文本计数器将毫无意义地增加一次。
在
CX
中移动用户输入的值也没有好处。您也可以从BL
使用它,甚至可以更好地使用它
add bl, al ;BL has user input 00..99
again:
mov ah, 09
mov dx, offset Hello
int 21h
mov dx, offset msg1
int 21h
mov dx, offset msg
int 21h
; This is the textual counter update
inc byte ptr msg ;Raise the ones
mov al, msg
cmp al, "9"
jbe SameDecade
mov byte ptr msg, "0" ;Reset the ones
inc byte ptr msg1 ;Raise the tens
SameDecade:
; This is the main loop counter update
sub bl, 1
jnb again
mov ax, 4C00h ;DOS.TerminateWithExitcode
int 21h
dec-cx
已经设置了标志(就像从cmp-cx,1
递减之前一样,如果您想具体说明它如何为jg
设置标志)decx/jnz
是一个有用的习惯用法。(当然,它没有设置CF,所以它与cmp
不太一样)@PeterCordes对,我只是按照最初的代码明确测试cx,我建议你可以说“用dec cx
/jnz
替换cmp cx,0
/jg
”。但事实上,我不确定这是否适合这个项目。我没有遵循全部逻辑;可能他们打算在reset
情况下不接触循环计数器,并有效地重试主循环的相同迭代。(如果没有跳转到reset
,则使用loopne
)如果只使用jge
/loop
,而不是让loopne
也检查标志并在==0x3a
的情况下失败,则更有意义。