程序集 - 程序按预期工作,但第二次运行时,打印出乱码

标签 assembly dos x86-16 tasm dosbox

我正在 TASM 汇编中制作程序(老实说,我不知道它是 16 位、x86、64 位还是 8086?我在 DOSBox 中使用 TASM 进行汇编、链接和测试。

用户输入字符,直到用户按下 Enter 键。然后将他们键入的内容回显到控制台。这是我的代码:

IDEAL
model small
STACK 100h

DATASEG
wholeinput db 00

CODESEG
start:

mov ax,@data
mov ds,ax
    mov bx, 0 ; bx is the counter

    input:
    mov ah, 1 ; input moves the input to al
    int 21h

    cmp al, 13 ; 0xD is enter key
    je enterPressed ; if its not 'enter' then continue
    add [wholeinput+bx], al ; add the given character to the end of the string

    inc bx    ; inc counter of string length
    jmp input ; continue loop


    enterPressed:
    add [wholeinput+bx], '$' ; add to the last byte of the thing a string terminator
    mov ah, 9
    mov dx, offset wholeinput ; print the whole thing
    int 21h


exit:
mov ax,4c00h
int 21h
END start

我第一次运行该程序时,它按预期运行。当我使用相同的输入第二次运行相同的程序时,它会向控制台打印乱码。

我的理论是,我上一次运行的内存以某种方式复制到下一次运行。这可能是一个非常愚蠢的说法,但我是一个菜鸟......

Screenshot

我的问题是什么?我该如何解决?

编辑: 感谢 Mike Nakis 和 Peter Cordes 提供此解决方案:
问题是我没有为输入预留足够的空间。

wholeinput db 00

只保留一个字节。修复:

wholeinput db 100 dup(0)

最佳答案

您的理论(之前运行的内存仍然存在)可能是正确的,根本不是一个愚蠢的想法。

db 00 只会为单个字节保留空间。因此,对于任何超过 0 个字节的输入,您都在写入 DATA 段的末尾。 (只需立即按 Enter 键,您的程序就会将 '$' 存储到该字节。)

对于 100 个零的数组,您需要 db 100 dup(0)。参见 What does `dup (?)` mean in TASM?

为什么保留不足的空间会导致这种特殊的行为,我不知道,老实说,这不是我期望的此类错误的行为。但话又说回来,在我们的职业中,各种奇怪的事情都会发生,当你看到问题最可能的原因是什么时,你可以快速解决它并继续你的生活,或者你可以花几个小时排除故障来尝试和准确找出观察到特定行为的原因。选择权在您。


我不确定 TASM 是否曾经为 16 位以外的任何东西制作过;在任何情况下,代码肯定看起来是 16 位的,并且这也肯定被 TASM 组装为 16 位,否则 model small 子句将给出错误,因为该子句仅存在于16 位模式。

关于程序集 - 程序按预期工作,但第二次运行时,打印出乱码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58272575/

相关文章:

linux - 如何用Fedora16测试汇编语言的LIDT指令?

c - 使用程序集中的 getchar 获取()函数

java - Apache HTTP 组件大小限制响应?

C:如何模拟8086寄存器?

assembly - x86 控制台滚动后出现奇怪的打印

assembly - ORG 汇编指令有什么作用?

c++ - 您如何获得程序使用了多少内存?

assembly - 从 NASM 到 GAS 的翻译

java - 如何在 vm 参数中提供 Windows 环境变量值?

assembly - MASM 字符串指令 - 在实模式下段寄存器覆盖前面的 LEA?