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

x86 Strange printing after console has been scrolled

我有以下功能:

printRows proc
    mov cx, 25
    printRowsLoop:  
        mov si, 0
        printSingleRowLoop:

            mov ah, 3  ;save current cursor position  at dx (dh:dl)
            int 10h

            push dx ;keep the position for later

            mov ah, 2
            mov dl, '&'   
            int 21h      ; print '&' char in the current curser position

            pop dx   ; restore dx

            add dl, 5 ; increase the column of it with a const number (so it would look like a square)
            mov ah, 2
            int 10h

            inc si
            cmp si, 3 ; print 3 '&' in each row
            jne printSingleRowLoop 

        mov dl, 13     ; result of these 3 groups of commands should be 2 new lines
        mov ah, 2
        int 21h

        mov dl, 10
        ;mov ah, 2 ; ah is alredy 2
        int 21h

        ;mov dl, 10 ; dl is already 10
        ;mov ah,2  ; ah is already 2
        int 21h

        loop printRowsLoop  ; print (cx) lines 
    ret

printRows endp

它的输出应该是在 this screenshot 中看到的 - 这是它的输出(至少在开头)

但是,在 "good" 输出填满控制台后(当它需要 "scroll" 时)它不再打印每个“&”之间的那些空格,而只是打印它们中的每一个在一个新行 as can be seen here.

什么可能导致这种奇怪的行为?我究竟做错了什么?我应该如何解决这个问题?

我用的是emu8086。

您的代码有一些问题:

  • BIOS 游标函数需要指定 BH 参数。它代表显示页面。最好设置为零。

  • BIOS GetCursor 调用将破坏循环控制所需的 CX 寄存器。您实际上不需要 CX 中返回的值,所以只需 PUSH/POP 它即可。

使用这个:

...
push cx
mov bh, 0  ;display page 0
mov ah, 3  ;save current cursor position  at dx (dh:dl)
int 10h    ;GetCursor
pop cx
...
mov bh, 0  ;display page 0
mov ah, 2
int 10h    ;SetCursor
...

通常这些更正不会解决滚动问题,但 emu8086 是一个有很多问题的程序。你可能会走运!

问题在于您插入换行符的方式。你做的是显示char 13, 10, 10。解决方法是在换行符(13, 10, 10, ' ') 后显示空白space :

mov dl, ' '
mov ah, 2
int 21h

要对齐第一行,我们必须在开头显示另一个space:

printRows proc
    mov ah, 2    ;<=============================================
    mov dl, ' '  ;<=============================================
    int 21h      ;<=============================================

    mov cx, 25
    printRowsLoop:  
        mov si, 0
        printSingleRowLoop:

            mov ah, 3  ;save current cursor position  at dx (dh:dl)
            int 10h

            push dx ;keep the position for later

            mov ah, 2
            mov dl, '&'   
            int 21h      ; print '&' char in the current curser position

            pop dx   ; restore dx

            add dl, 5 ; increase the column of it with a const number (so it would look like a square)
            mov ah, 2
            int 10h

            inc si
            cmp si, 3 ; print 3 '&' in each row
            jne printSingleRowLoop 

        mov dl, 13     ; result of these 3 groups of commands should be 2 new lines
        mov ah, 2
        int 21h

        mov dl, 10
        ;mov ah, 2 ; ah is alredy 2
        int 21h

        ;mov dl, 10 ; dl is already 10
        ;mov ah,2  ; ah is already 2
        int 21h

        mov dl, ' ' ;<=============================================
        mov ah, 2   ;<=============================================
        int 21h     ;<=============================================

        loop printRowsLoop  ; print (cx) lines 
    ret

printRows endp

最后打印回车return(13 ascii码)

我的回答中也包含了 Fifoernik 的提示。

printRows proc
mov cx, 25
printRowsLoop:  
    mov si, 0
    printSingleRowLoop:

        push cx
        mov bh, 0
        mov ah, 3  ;save current cursor position  at dx (dh:dl)
        int 10h  
        pop cx


        push dx ;keep the position for later

        mov ah, 2
        mov dl, '&'   
        int 21h      ; print '&' char in the current curser position

        pop dx   ; restore dx

        mov bh, 0
        add dl, 5 ; increase the column of it with a const number (so it would look like a square)
        mov ah, 2
        int 10h

        inc si
        cmp si, 3 ; print 3 '&' in each row
        jne printSingleRowLoop 


        mov dl, 10
        ;mov ah, 2 ; ah is alredy 2
        int 21h

        ;mov dl, 10 ; dl is already 10
        ;mov ah,2  ; ah is already 2
        int 21h

        mov dl, 13    ; <<<<<<<<<<<<<<<<<<<<< print the carriage return last!
        ;mov ah, 2 ; ah is already 2 
        int 21h  

    loop printRowsLoop  ; print (cx) lines 
ret

printRows endp

不需要额外的 space 个字符:)