装配循环错误
Assembly Loop Error
我正在尝试用汇编 (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 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
[=18=的东西]
你不是改cx,比较前在cmp cx, 0
前加dec cx
只是建议:您不需要使用 jmp again
或 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
我正在尝试用汇编 (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 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
[=18=的东西]你不是改cx,比较前在
cmp cx, 0
前加
dec cx
只是建议:您不需要使用 jmp again
或 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