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

bprjcwpo  于 2023-10-19  发布在  iOS
关注(0)|答案(1)|浏览(127)

中断ah=0Ehint 10h在屏幕上显示一个字符,它有几个参数,包括BH,它应该指示页码,除了经过几次测试我意识到BH是绝对无用的。即使我更改了页码,字符仍然会显示在活动页面上。
Ralf Brown's interrupt list says
“日期为1981/4/24和1981/10/19的IBM PC ROM要求BH与当前活动页相同”
互联网上的一个页面是这样写的:https://www.ic.unicamp.br/~celio/mc404-2004/service_interrupts#int10h_0Eh
此函数在屏幕上显示一个字符,根据需要推进光标并滚动屏幕。打印始终在当前活动页面上进行。
我必须信任哪个来源,我使用没有操作系统的虚拟机,我使用 Bootstrap 。
我明确表示我不理解此信息
日期为1981/4/24和1981/10/19的IBM PC ROM要求BH与当前活动页面相同
知道我使用虚拟盒子,我不认为虚拟盒子使用的是1981年IMG PC的ROM?

ao218c7q

ao218c7q1#

服务ah = 0x0Eint 0x10仅在活动页面上打印。您可以使用服务ah = 0x05al = page numberint 0x10更改活动页面。
BH不应该是这个BIOS函数的输入。Ralf Brown的中断列表只是作为它提到的两个早期IBM-PC BIOS版本(1981/4/24和1981/10/19)中BH需要保存活动页码的bug的一部分而显示的。否则它根本不是输入。
我查看了BIOS 1981-04-24、1981-10-19和1982-10-27的代码,前两个BIOS中的服务ah = 0x0Ewrite_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 = 0x03read_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 Bootstrap 中使用它的例子。这在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

相关问题