Assembly 英特尔8086-输入数字后程序锁定

Assembly 英特尔8086-输入数字后程序锁定,assembly,x86-16,dosbox,8086,Assembly,X86 16,Dosbox,8086,我对汇编语言非常陌生,我正在做一项作业,要求你输入一个数字,要么输入一个零,要么输入九个数字,将它们存储在堆栈中,然后在输入完数字后将数字相加,并将总和打印到屏幕上。当我组装并链接程序及其外部文件时,它不会出现任何错误;但是,当我运行代码时,它会打印一个空行(没有其他内容),让我输入一个数字,锁定并关闭DOSBox。我一直在试图找出问题所在以及如何解决,但我完全被卡住了。任何帮助都将不胜感激,谢谢 .model small .stack 100h .data count db 0

我对汇编语言非常陌生,我正在做一项作业,要求你输入一个数字,要么输入一个零,要么输入九个数字,将它们存储在堆栈中,然后在输入完数字后将数字相加,并将总和打印到屏幕上。当我组装并链接程序及其外部文件时,它不会出现任何错误;但是,当我运行代码时,它会打印一个空行(没有其他内容),让我输入一个数字,锁定并关闭DOSBox。我一直在试图找出问题所在以及如何解决,但我完全被卡住了。任何帮助都将不胜感激,谢谢

.model small
.stack 100h
.data
    count db 0
    sum dw 0
    prompt db 0ah, 0dh, 'Enter Value ', '$'
    colon db ': ','$'
    reply db 0ah, 0dh, 'Sum Equals: ', '$'
.code
    extrn indec: proc
    extrn outdec: proc
    include myMacros.asm

    mov ax,@data
    mov ds,ax

    mov cx,0
    mov bx,0
    
    push cx
    ;jmp L1
    
L1:
    inc count
    prtStr prompt
    mov cl,count
    writeCh count
    prtStr colon
    call indec
    cmp ax,0
    je S
    push ax
    cmp cx,9
    jl L1
    
S:
    pop dx
    add bx,dx
    cmp dx,0
    jne S

    ;prtStr reply
    mov ax,bx
    call outdec
    exit
    
endp
    
end
因为您没有显示这些宏,我们只能推测它们是如何运行的。
但是,看到您在程序中很早(太早)就将
BX
CX
寄存器(其余代码所依赖的)归零,我猜这些
调用和宏调用中的一个或多个可能会改变这些寄存器

但有一个错误是显而易见的。如果宏writeCh确实写入Ch字符,则应在count变量中存储合适的ASCII码。现在您有了数字[1,9],您希望字符[“1”,“9”]对应于ASCII码[49,57]

.data
    count db '0'       ; This is a character '0' with ASCII code 48
    ...
.code
    ...
    push    0          ; Sentinel (*)
L1:
    prtStr  prompt
    inc     count
    writeCh count
    prtStr  colon
    call    indec      ; -> AX
    test    ax, ax
    jz      S
    push    ax
    cmp     count, '9' ; Loose the dependency on the CX register
    jb      L1         ; Treat ASCII code as UNsigned numbers
    
S:
    xor     ax, ax     ; Setup close to the consumer and as late as you can. This will
S_:                    ; improve readability and probably avoid errors too...
    pop     dx
    add     ax, dx
    test    dx, dx     ; Got to sentinel ?
    jnz     S_         ; Not yet

    push    ax         ; In case 'prtStr' clobbers AX
    prtStr  Reply
    pop     ax
    call    outdec
    ...
(*)如果您在标题中对的引用是严格的,则必须将此
push 0
替换为对
xor ax,ax
push ax

因为您没有显示这些宏,我们只能推测它们是如何运行的。
但是,看到您在程序中很早(太早)就将
BX
CX
寄存器(其余代码所依赖的)归零,我猜这些
调用和宏调用中的一个或多个可能会改变这些寄存器

但有一个错误是显而易见的。如果宏writeCh确实写入Ch字符,则应在count变量中存储合适的ASCII码。现在您有了数字[1,9],您希望字符[“1”,“9”]对应于ASCII码[49,57]

.data
    count db '0'       ; This is a character '0' with ASCII code 48
    ...
.code
    ...
    push    0          ; Sentinel (*)
L1:
    prtStr  prompt
    inc     count
    writeCh count
    prtStr  colon
    call    indec      ; -> AX
    test    ax, ax
    jz      S
    push    ax
    cmp     count, '9' ; Loose the dependency on the CX register
    jb      L1         ; Treat ASCII code as UNsigned numbers
    
S:
    xor     ax, ax     ; Setup close to the consumer and as late as you can. This will
S_:                    ; improve readability and probably avoid errors too...
    pop     dx
    add     ax, dx
    test    dx, dx     ; Got to sentinel ?
    jnz     S_         ; Not yet

    push    ax         ; In case 'prtStr' clobbers AX
    prtStr  Reply
    pop     ax
    call    outdec
    ...

(*)如果您在标题中对的引用是严格的,那么这个
push 0
必须替换为一对
xor ax,ax
push ax

作为一个开始,您可能应该查看mymacros.asm中的代码。仅根据名称,我猜
outdec
不用于显示字符串。更可能的情况是,它接受al中的值,将其转换为字符串并显示。这样做
mov al,提示;call outdec
不会按您的意愿进行操作。因此,现在它会打印一个空行,让我输入一个数字,然后它不会让我输入任何其他内容,但它不会关闭DOSBox,并且光标会一直闪烁,因此您所说的更改很有帮助,谢谢!我猜我的问题现在出在L1的某个地方,但我不确定。关于修复什么,您还有其他建议吗?在修复程序时,通常最好按照程序出现的顺序进行修复。有时候你遇到(严重的)问题5是因为(不是很严重的)问题1把事情搞砸了。如果您仍然没有收到提示,您可能应该找到它。如果您计划学习汇编语言(或者任何编程语言),您需要学习如何使用调试器。我不熟悉您正在使用的汇编程序,但我怀疑调试器会向您显示在
mov cl,count
处发生的奇怪情况。如果不在数据和cx中保留计数,而只使用cx呢?我建议使用Turbo Debugger 2.01,它可以很好地处理DOSBox中的16位可执行文件:首先,您可能应该看看mymacros.asm中的代码。仅根据名称,我猜
outdec
不用于显示字符串。更可能的情况是,它接受al中的值,将其转换为字符串并显示。这样做
mov al,提示;call outdec
不会按您的意愿进行操作。因此,现在它会打印一个空行,让我输入一个数字,然后它不会让我输入任何其他内容,但它不会关闭DOSBox,并且光标会一直闪烁,因此您所说的更改很有帮助,谢谢!我猜我的问题现在出在L1的某个地方,但我不确定。关于修复什么,您还有其他建议吗?在修复程序时,通常最好按照程序出现的顺序进行修复。有时候你遇到(严重的)问题5是因为(不是很严重的)问题1把事情搞砸了。如果您仍然没有收到提示,您可能应该找到它。如果您计划学习汇编语言(或者任何编程语言),您需要学习如何使用调试器。我不熟悉您正在使用的汇编程序,但我怀疑调试器会向您显示在
mov cl,count
处发生的奇怪情况。如果不在数据和cx中保留计数,而只使用cx呢?我建议使用Turbo Debugger 2.01,它可以很好地处理DOSBox中的16位可执行文件: