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

时间:2016-06-01 21:29:38

标签: assembly x86 x86-16 emu8086

我有以下功能:

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中看到的 - 这是它的输出(至少在begginig中)

但是,在“好”输出填满控制台之后(当需要“滚动”时)它不再打印每个'&'之间的那些空格,而只是在新行中打印它们中的每一个{ {3}}

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

我正在使用emu8086。

3 个答案:

答案 0 :(得分:4)

你应该最后打印回车符(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

不需要额外的空格字符:)

答案 1 :(得分:2)

您的代码存在一些问题:

  • 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是一个有很多问题的程序。你可能会很幸运!

答案 2 :(得分:0)

问题在于插入换行符的方式。你要做的是显示字符13,10,10。解决方案是在换行符后显示一个空格(13,10,10,&#39;&#39;):

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

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

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