为什么 BIOS 电传打字功能中不使用 BH 作为参数(`ah=0Eh` `int 10h`)?

问题描述 投票:0回答:1

中断

ah=0Eh
int 10h
在屏幕上显示一个字符,它有几个参数,其中包括BH,它应该表示页码,只不过经过几次测试我发现BH完全没有用。即使我更改页码,角色仍然会显示在活动页面上。

拉尔夫·布朗的中断列表说

“1981/4/24 和 1981/10/19 的 IBM PC ROM 要求 BH 与当前活动页面相同”

互联网上的一个页面这样写:https://www.ic.unicamp.br/~celio/mc404-2004/service_interrupts#int10h_0Eh

此功能在屏幕上显示一个字符,根据需要前进光标并滚动屏幕。打印始终在当前活动页面完成。

我必须信任哪个来源,我使用没有操作系统的虚拟盒子,并且我使用引导加载程序。

我明确表示我不明白此信息

1981/4/24 和 1981/10/19 的 IBM PC ROM 要求 BH 与当前活动页面相同

知道我使用 Virtual Box,我不认为 Virtual Box 使用 1981 年 IMG PC 上的 ROM?

assembly virtualbox interrupt x86-16 bios
1个回答
7
投票

服务

ah = 0x0E
int 0x10
仅在活动页面上打印。您可以使用服务
ah = 0x05
al = page number
int 0x10
更改活动页面。

BH 不应该是此 BIOS 功能的输入。 Ralf Brown 的中断列表仅将其显示为记录其提到的两个早期 IBM-PC BIOS 版本(1981/4/24 和 1981/10/19)中的 bug 的一部分,其中 BH 需要保存活动页码。否则根本就不是输入。


我查看了BIOS 1981-04-24、1981-10-19和1982-10-27的代码,前两个BIOS中的服务

ah = 0x0E
write_tty)是这样启动的:

WRITE_TTY PROC    NEAR
  PUSH    AX      ; SAVE REGISTERS
  PUSH    AX      ; SAVE CHAR TO WRITE
  MOV AH,3
  INT 10H         ; READ THE CURRENT CURSOR POSITION
  POP AX          ; RECOVER CHAR

  . . .

;------ WRITE THE CHAR TO THE SCREEN

  MOV BH,ACTIVE_PAGE  ; GET THE CURRENT ACTIVE PAGE
  MOV AH,10       ; WRITE CHAR ONLY
  MOV CX,1        ; ONLY ONE CHAR
  INT 10H

开头有服务

ah = 0x03
read_cursor)需要
bh = page number
计算活动页面上光标位置的偏移量,该值在DX中返回并存储在这里:

  CURSOR_POSN DW  8 DUP(?)    ; CURSOR FOR EACH OF UP TO 8 PAGES

稍后我们有指示

mov bh,active_page
。例如,我们要写入第 0 页,我们计算第 0 页上的光标位置,但 active_page = 1,因此我们不匹配。所以也许这就是 RBIL 页面谈论它的原因,BH 应该与 active_page 相同。

1981/4/24 和 1981/10/19 的 IBM PC ROM 要求 BH 与当前活动页面相同

在最新的 BIOS 1982-10-27 中,行

MOV BH,ACTIVE_PAGE
更改了位置

WRITE_TTY PROC    NEAR
  PUSH    AX          ; SAVE REGISTERS
  PUSH    AX          ; SAVE CHAR TO WRITE
  MOV AH,3
  MOV BH,ACTIVE_PAGE      ; GET THE CURRENT ACTIVE PAGE
  INT 10H         ; READ THE CURRENT CURSOR POSITION
  POP AX          ; RECOVER CHAR

BH 与 active_page 相同。因此程序计算正确页面的位置。


这是在 BIOS MBR 引导加载程序中使用它的示例。这在 QEMU 中效果很好:

[org 0x7C00]

section .text
    global main

main:   
    mov ax,0
    mov ds,ax
    mov ss,ax
    mov sp,0x7C00

    mov ax,0x0003
    int 0x10

    mov ah, 0x0E
    mov si, msg1    
    
Msg_1:
    lodsb                
    or al,al
    jz WaitKeyPress1
    int 0x10        
    jmp Msg_1

WaitKeyPress1:
    mov ah,0x00
    int 0x16
    
    mov ah,0x05
    mov al,0x01
    int 0x10
    
    mov ah,0x0E
    mov si,msg2
    
Msg_2:
    lodsb                
    or al,al
    jz WaitKeyPress2
    int 0x10        
    jmp Msg_2   

WaitKeyPress2:
    mov ah,0x00
    int 0x16
    
    mov ah,0x05
    mov al,0x00
    int 0x10

Done:   
    jmp Done

msg1 db "This message is printed on page 0."
        db 13,10,"Press any key to change page to 1...",0
    msg2 db "And this message is printed on page 1."
        db 13,10,"Press any key to go back to page 0.",0

    
    times 510 - ($ - $$) db 0
    dw 0xAA55

这可以从命令行运行,如 DOS .COM:

[org 100h]
    
section .data
    msg1 db "This message is printed on page 0."
        db 13,10,"Press any key to change page to 1...",0
    msg2 db "And this message is printed on page 1."
        db 13,10,"Press any key to go back to page 0.",0
        

section .text
    global main

main:   
    mov ax,0x0003
    int 0x10

    mov ah, 0x0E  
    mov si, msg1    
    
Msg_1:
    lodsb                
    or al,al
    jz WaitKeyPress1
    int 0x10        
    jmp Msg_1

WaitKeyPress1:
    mov ah,0x08
    int 0x21
    
    mov ah,0x05
    mov al,0x01
    int 0x10
    
    mov ah,0x0E
    mov si,msg2
    
Msg_2:
    lodsb                
    or al,al
    jz WaitKeyPress2
    int 0x10        
    jmp Msg_2   

WaitKeyPress2:
    mov ah,0x08
    int 0x21
    
    mov ah,0x05
    mov al,0x00
    int 0x10

Done:   
    mov ax,4C00h
    int 21h
© www.soinside.com 2019 - 2024. All rights reserved.