【问题标题】:Intel 8086 - Program Locks Up After Entering a NumberIntel 8086 - 输入数字后程序锁定
【发布时间】:2020-11-23 21:55:41
【问题描述】:

我真的是汇编语言的新手,我正在做一个假设要求你输入一个数字的作业,直到你输入一个零或直到你输入九个数字,将它们存储在堆栈中,然后在输入完数字后将数字相加,并将总和打印到屏幕上。当我组装和链接程序及其外部文件时,它没有出现任何错误;但是,当我运行代码时,它会打印一个空行(没有其他内容),让我输入一个数字,锁定并关闭 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

【问题讨论】:

  • 首先,您应该看看 mymacros.asm 中的代码。仅基于名称,我猜outdec 不打算显示字符串。更有可能的是,它采用 al 中的值,将其转换为字符串并显示出来。所以mov al,prompt; call outdec 不会达到你想要的效果。
  • 所以现在它打印一个空白行,让我输入一个数字,然后它不会让我输入任何其他内容,但它不会关闭 DOSBox 并且光标一直在闪烁,所以你说的改变有帮助,谢谢!我猜我的问题现在出在 L1 的某个地方,但我不确定。对于要解决的问题,您还有其他建议吗?
  • 修复程序时,最好按照它们出现的顺序来修复它们。有时您遇到(严重)问题#5 的原因是因为(不是很严重)问题#1 把事情搞砸了。如果您仍然没有收到提示,您可能应该追踪它。如果您打算学习汇编程序(或任何编程语言),您需要学习如何使用调试器。我不熟悉您使用的汇编程序,但我怀疑调试器会在mov cl,count 向您展示一些奇怪的事情。如果您不同时在 data 和 cx 中保留计数,而是只使用 cx 会怎样?
  • 我可以推荐 Turbo Debugger 2.01,它适用于 DOSBox 中的 16 位可执行文件:cs.nyu.edu/courses/fall99/V22.0201-002/debug.html

标签: assembly x86-16 dosbox


【解决方案1】:
include myMacros.asm

因为您没有显示这些宏,所以我们只能推测它们的操作方式。
但是,看到您在程序中很早(太早)将BXCX 寄存器(其余代码依赖)归零,我猜这些call 和宏中的一个或多个-调用可能会改变这些寄存器。

一个错误是显而易见的。如果宏 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, axpush ax 对。

【讨论】:

    猜你喜欢
    • 2021-12-27
    • 1970-01-01
    • 2015-07-18
    • 1970-01-01
    • 2014-01-16
    • 2014-12-06
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    相关资源
    最近更新 更多