为什么我的打印函数第二次调用后输出错误? (x86 程序集)

Why is the output wrong after the second call of my print function? (x86 Assembly)

我写了一个由 BIOS 引导的简单汇编程序,我写了一个函数将寄存器 (E)SI 的内容输出到屏幕

我有一个名为 msg 的变量,它是一个字符串 "Hello World1", 0xa, "Hello World2", 0xa, "Hello World3", 0xa, 0xa, 0x0

如果我使用该函数一次,输出将是:

Hello World1
Hello World2
Hello World3

但是如果我使用它两次,输出将是这样的:

Hello World1
Hello World2
Hello World3

Hello World1
                          Hello World2
                          Hello World3

为什么我使用了两次打印功能会出错?

我的代码:


[ORG 0x7c00]

    xor     ax, ax
    mov     ds, ax
    mov     ss, ax
    mov     sp, 0x9c00
    mov     ax, 0xb800
    mov     gs, ax

    call    clear

    mov     si, msg
    mov     ah, 4
    call    print

    mov     si, msg
    mov     ah, 4
    call    print

    cli
    jmp     $

print:
    mov     bx, [vaddr]

write:
    lodsb
    cmp     al, 0
    je      end_write
    cmp     al, 0xa
    je      new_line
    mov     [gs:bx], ax
    add     bx, 2
    jmp     write

new_line:
    mov     cx, [vline]
    add     cx, 160
    mov     [vline], cx
    sub     cx, bx
    add     bx, cx

    jmp write

end_write:
    mov     [vaddr], bx
    ret

clear:
    mov     ah, 0
    mov     al, ' '
    xor     bx, bx

    mov     cx, 2000

clear_char:
    mov     [gs:bx], ax
    add     bx, 2
    loop    clear_char

    mov     byte [vaddr], 0
    mov     byte [vline], 0
    ret

msg:        db      "Hello World1", 0xa, "Hello World2", 0xa, "Hello World3", 0xa, 0xa, 0x0
vaddr:      db      0x0
vline:      dd      0

    times 510-($-$$) db 0
    db 0x55
    db 0xAA

感谢您的帮助

这些变量的定义:

vaddr:      db      0x0             BYTE
vline:      dd      0               DWORD

这些变量的设置:

mov     byte [vaddr], 0             BYTE
mov     byte [vline], 0             BYTE

这些变量的使用:

mov     bx, [vaddr]                 WORD
mov     cx, [vline]                 WORD 

只需确保在任何地方都使用 WORD