首页 > 解决方案 > BIOS 调用的引导加载程序键盘输入问题

问题描述

所以我跟着一个关于如何制作操作系统的教程,我想制作一个程序,它需要一个字符并打印它,但它不起作用。

这里是源代码

[org 0x7c00]

mov ah, 0
int 0x16
mov al, [test]

mov bx, test
call print

jmp $

print:
    mov ah, 0x0e
    loop:
        cmp [bx], byte 0
        je exit

        mov al, [bx]
        int 0x10
        inc bx
        jmp loop
    exit:
    ret

test:
    db 0

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

标签: assemblyx86-16bootloaderbios

解决方案


正如@Jester 在评论中指出的那样,您需要将 BIOS.GetKeyboardKey 函数 00h 的 ASCII 输出存储在测试变量中,而不是相反。
现在,如果您纠正了这一点,您的程序有可能并且很可能运行良好,但我们不应该过早欢呼!由于您没有设置DS段寄存器,因此该指令很容易mov [test], al覆盖其他一些您不会注意到的内存位置,除非发生崩溃......

  • 你需要一个正确DS的变量test来解决。

  • 打印子例程中使用的 BIOS.Teletype 函数 0Eh需要 DisplayPage 参数 inBH和(图形)颜色 in BL。你永远不应该使用BX来指向消息!为此使用SI或。DI

  • 另请注意,您的打印代码需要一个以零结尾的字符串,但您实际上并未提供该零!

这是代码的更正版本:

[org 0x7C00]

  xor  ax, ax
  mov  ds, ax

  mov  ah, 00h    ; BIOS.GetKeyboardKey
  int  0x16       ; -> AX
  mov  [test], al ; Store ASCII in zero-terminated string

  mov  di, test
  call print

  jmp  $

print:
  mov  bx, 7     ; BH=0 DisplayPage, BL=7 Color White
.loop:
  mov  al, [di]
  cmp  al, 0
  je   .exit
  mov  ah, 0x0E  ; BIOS.Teletype
  int  0x10
  inc  di
  jmp  .loop
.exit:
  ret

test:
  db 0, 0

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

推荐阅读