首页 > 解决方案 > 为什么中断int 21h在程序执行期间写入填充的字符串后会忽略所有字符串?

问题描述

我正在尝试打印两个 16Bit 值的总和,因此正在计算总和然后构造包含它的字符串,但问题是在我打印所述字符串后,任何写入中断mov ah,09 int 21h都将被完全忽略,我使用的是 emu8086,这是代码

org 100h

    mov ax,2000
    mov bx,3200
    add ax,bx
    mov si,offset result+5
    mov [si],'$'
    mov bx,10

    Fill:

        dec si
        mov dx,0
        div bx
        add dl,48
        mov [si],dl
        test ax,ax

    jnz Fill

    mov dx,offset result
    mov ah,09h
    int 21h

    mov ah,09h
    mov dx,offset msg
    int 21h

ret

result db 5 dup (?)
msg db " is the sum$"
\n db 0ah,0dh, '$'

它只是打印result并忽略msg

标签: assemblydosx86-16emu8086

解决方案


result db 5 dup (?)
msg    db " is the sum$"

使用这些数据定义,内存设置如下:

result 0    <- offset result+0
       0    <- offset result+1
       0    <- offset result+2
       0    <- offset result+3
       0    <- offset result+4
msg         <- offset result+5   <- offset msg+0
       i                         <- offset msg+1
       s                         <- offset msg+2
                                 <- offset msg+3
       t                         <- offset msg+4
       h                         <- offset msg+5
       e                         <- offset msg+6
                                 <- offset msg+7
       s                         <- offset msg+8
       u                         <- offset msg+9
       m                         <- offset msg+10
       $                         <- offset msg+11

当您在 处为结果编写终止 $时offset result+5,您会覆盖msg文本开始的那个空格字符。这反过来意味着当您要求 DOS 显示msg文本时,DOS 会立即偶然发现字符串终止符,因此不会显示任何内容。

解决方案是不要将 $ 字符写在offset result+4

相反,您需要为结果扩大缓冲区,以便它可以容纳6个字节。
您转换的寄存器中的值AX可能需要 5 位数字。因此,您需要一个 5+1 字节的缓冲区。

result db 6 dup (?)

作为避免必须通过代码编写 $ 字符的快捷方式,有:

result db 5 dup (?), '$'

mov dx,offset result
mov ah,09h
int 21h

使用结果的偏移量可能会在屏幕上产生垃圾!
这里好的解决方案是SI在转换结束时使用寄存器中的值。它已经指向数字的第一位。多么方便!

    org  100h

    mov  ax, 2000
    mov  bx, 3200
    add  ax, bx
    mov  si, offset result+5
    mov  [si], '$'
    mov  bx, 10

Fill:

    dec  si
    xor  dx, dx
    div  bx
    add  dl, '0'
    mov  [si], dl
    test ax, ax
    jnz  Fill

    mov  dx, si            <- This is offset of first digit.
    mov  ah, 09h
    int  21h

    mov  ah, 09h
    mov  dx, offset msg
    int  21h
    ret

result   db 6 dup (?)
msg      db " is the sum$"

推荐阅读