【问题标题】:Function 06h of interrupt 10h. Scrolling text line up中断 10h 的功能 06h。滚动文本排列
【发布时间】:2016-03-09 14:09:04
【问题描述】:

我需要使用中断 10h 的函数 06h 来实现滚动队列。问题是我有滚动线,但符号没有出现,光标消失了,什么也没有发生。也许我忘记了要考虑的事情?要编写代码,我使用FASM。该代码是引导加载程序的一部分。这是与滚动相关的一段代码:

cmp cx, 2001
je ScrollLine

我有一个计数器,当它达到 2001(从 1 开始计数)时,控制权传递给 ScrollLine。

滚动线:

mov ah, 06h
mov al, 1
mov bh, 07      
mov cx, 0000h
mov dx, 184Fh 
int 10h
ret

我完整的bootloader代码如下:

use16
org 7C00h

start:
    mov ah, 00h  
    mov al, 02h              
    int 10h

    mov ax, NewInt40
    call ChangeIVT

    mov cx, 0

wait_loop:
    xor ax, ax

    inc cx

    cmp cx, 2001
    je ScrollLine

    mov ah, 0
    int 16h

    push ax
    call PrintChar

    jmp wait_loop

NewInt40:   
    sti
    push ax
    mov ax, msg
    cmp bl, 3
    je PrintChar
    cmp bl, 2
    je PrintString
    cmp bl, 1
    je Clear
    cmp bl, 4
    je Scroll
    pop ax
    iret

ChangeIVT:

    push bx
    xor bx, bx

    mov es, bx
    mov bx, 40h
    shl bx, 2

    mov word [es:bx], ax
    mov word [es:bx+2], 0

    pop bx
    ret

PrintString:

    push si
    push bx
    push es
    mov si, ax

    mov ax, 0B800h
    mov es, ax

    xor bx, bx
    xor dx, dx

@@:
    lodsb   

    cmp al, 0
    je @f

    mov byte [es:bx], al
    mov byte [es:bx+1], 1Eh

    mov ah, 0Eh
    add bx, 2
    inc dx
    mov ah,02h
    mov al,02h  
    int 10h
    jmp @b

@@:
    pop es
    pop bx
    pop si
    ret

PrintChar:

    push bp
    mov bp, sp
    push bx
    push es
    push cx

    mov ax, 0B800h
    mov es, ax

    xor bx, bx
    xor dx, dx

    mov ah,3
    int 0x10

    movzx ax, dh
    movzx bx, dl
    mov cx, 80
    push dx
    mul cx
    pop dx
    add bx, ax  ; bx = 80 * dh + dl
    shl bx, 1   ; bx = 2 * (80 * dh + dl)



    mov ax, [bp + 4]
    mov byte [es:bx], al
    mov byte [es:bx+1], 1Eh

    cmp dl, 79
    jl @f

    inc dh
    mov dl, -1
@@:
    inc dl

    pop cx
    mov bh, 0

    mov ah, 2
    int 0x10

    pop es
    pop bx
    mov sp, bp
    pop bp
    ret

Clear:
   mov  AH,0      
   mov  AL,2      
   int  10H       
   ret

Scroll:
    mov ah, 06h
    mov al, 1
    mov bh, 07      
    mov cx, 0000h
    mov dx, 184Fh 
    int 10h
    ret

ScrollLine:
    mov bl, 4
    int 40h
    xor cx, cx
    ret

msg db "Hello, world!", 0Dh, 0Ah, 0

db 510-($-$$) dup (0)

db 55h, 0AAh

【问题讨论】:

  • 所以你正在制作例如一个 09h 之后显示一个字符,那是问题出现的时候?文本滚动,但您随后遇到了输出问题?
  • 你能再贴一些代码吗? This 简单的演示程序(用于 NASM)使用与您相同的中断调用并且工作正常。
  • @MargaretBloom:有点吹毛求疵,但在您的代码中,当您创建 COM 程序(我假设来自 org 100h)时,设置 SS:SP、DS 等有什么意义? DOS 加载程序自动加载 COM 程序并将它们全部设置到同一段,并在 64k 段的顶部适当地设置堆栈。 CS=DS=SS 都指向 PSP 段的开始。
  • @MichaelPetch。噢 .. 引导加载程序编码的坏习惯。 :)
  • @Tommy 是的。我有一个处理键盘输入的循环。 wait_loop: xor ax, ax inc cx cmp cx, 2001 je ScrollLine mov ah, 0 int 16h jmp wait_loop

标签: assembly x86 bootloader fasm video-memory


【解决方案1】:

你用跳跃跟注。

NewInt40 ISR 中,您有条件地跳转到子例程PrintStringPrintCharScroll 等,但从它们返回ret

我不知道代码的结构是怎样的,所以我只介绍了使其工作所需的最小更改,没有什么可以称为良好实践时间>。

既然您正在编写引导加载程序,那么您现在肯定知道要修复什么了。

NewInt40:   
    sti
    push ax

    push bp             ;; Save caller's BP
    mov bp, sp          ;; Save SP, so we can restore the stack pointer

    push WORD _ni40_end ;; Push return address of every routine

    mov ax, msg
    cmp bl, 3
    je PrintChar
    cmp bl, 2
    je PrintString
    cmp bl, 1
    je Clear
    cmp bl, 4
    je Scroll


_ni40_end:          ;; NASM label
    mov sp, bp      ;; Restore stack pointer (in any case) 
    pop bp          ;; Restore caller BP

    pop ax
    iret

对不起,我是为 NASM 写的,不过翻译成 FASM 应该很容易。

附言
当您的引导加载程序“发疯”时,例如没有响应或自行操作,很可能是您“失去执行流程”的症状。
这意味着您正在执行不是您的代码的字节,当您返回不平衡的堆栈时会发生这种情况。
如果类似的事情再次发生,请仔细检查您的退货。

【讨论】:

  • 他在je ScrollLine 时也犯了类似的错误。 Scrollline 也执行ret
  • 他的代码中的另一个特殊问题是 push ax call PrintChar 。我没有看到他在调用完成后清理堆栈并删除参数。
  • @MichaelPetch 我明白了这一切,但我需要一个返回程序的条件跳转。毕竟,如果我要使用call,我就无法达到这个条件。我很抱歉我的英语。并感谢您的所有 cmets 和更正
  • @MargaretBloom @MichaelPetch 我知道我犯了一个错误。但我不知道如何在一个条件下制作call。我只知道一种方法 - cmp 与 j(e, ne, a, etc.)。是的,使用 ret 而不使用 call 是不可接受的。我得到它。我现在只是有点困惑
  • @P.Fiona Margaret 提出了一种可能的解决方案。您手动将返回地址压入堆栈,执行条件跳转,然后ret 将返回压入堆栈的地址。或者(可能对您的思维方式更简单)是有条件地跳转到标签,然后调用预期的函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
相关资源
最近更新 更多