在保护模式下将字符打印到屏幕 ASM

Printing characters to screen ASM in protected mode

我正在尝试进入保护模式然后打印出来"Hi"

但它只是从我的 bios 中断调用(在进入 pmode 之前发生)打印 "Loading OS" 而没有别的。

我的Bootloader.asm

%DEFINE KERNEL_LOAD_OFFSET 0x1000

org 0x7c00

bits 16

xor ax, ax
mov ds, ax

start: jmp main

Print:
 .print:
  lodsb
  or al, al
  je .done

  mov ah, 0x0E
  int 0x10

  .repeat:
   jmp .print

 .done:
  ret

ResetFloppy:
 mov ah, 0x0

 int 0x13
 jc ErrorFloppy
 .done:
  ret

ReadFloppy:

 mov ah, 0x02
 int 0x13

 jc ErrorFloppy

 .done:
  ret

ErrorFloppy:

 mov si, msgErrorFloppy
 call Print

 jmp hang


main: 
 .print:

  mov si, msg
  call Print

 .loadFile:
  mov al, 0xF
  mov ch, 0x0
  mov cl, 0x02
  mov dh, 0x0
  mov dl, 0x0
  mov bx, KERNEL_LOAD_OFFSET

  call ResetFloppy
  call ReadFloppy


 .loadGDT:
   lgdt [gdtr]
 .pM_start:
  cli
  pusha

  mov eax, cr0
  or al, 1
  mov cr0, eax

  popa

  jmp 0x08:ljmp_pM


 bits 32
 ljmp_pM: 
  mov ax, 0x10
  mov ds, ax
  mov ss, ax
  mov fs, ax
  mov es, ax
  mov gs, ax

  jmp KERNEL_LOAD_OFFSET

hang:
 jmp $

gdt:
NULL_DESC:
    dd 0            ; null descriptor
    dd 0

CODE_DESC:
    dw 0xFFFF       ; limit low
    dw 0            ; base low
    db 0            ; base middle
    db 10011010b    ; access
    db 11001111b    ; granularity
    db 0            ; base high

DATA_DESC:
    dw 0xFFFF       ; data descriptor
    dw 0            ; limit low
    db 0            ; base low
    db 10010010b    ; access
    db 11001111b    ; granularity
    db 0            ; base high

gdtr:
    Limit dw 24         ; length of GDT
    Base dd NULL_DESC   ; base of GDT

msg db "Loading OS", 13, 10, 0
msgErrorFloppy db "There was an error with the floppy", 13, 10, 0

FILL:
 times 510-($-$$) db 0

BOOTSECTOR:
 dw 0xAA55

Kernel.asm

bits 32

mov dword [0xB8000], 0x07690748

jmp $

Compile.bat

nasm -f bin Dev/BootLoader.asm -o Bin/BootLoader.bin
nasm -f bin Dev/Kernel.asm -o Bin/Kernel.bin

dd if=Bin/BootLoader.bin of=Image/Image.img seek=0
dd if=Bin/Kernel.bin of=Image/Image.img seek=1 conv=notrunc

pause

我用的是bochs。我得到的只是:http://prntscr.com/d24wmm

在 32 位保护模式下,您无法使用 BIOS,因为它是用 16 位实模式代码编写的。所以,你必须像这样访问显存:

    mov ebx,0xb8000    ; The video address
    mov al,'!'         ; The character to be print
    mov ah,0x0F        ; The color: white(F) on black(0)
    mov [ebx],ax        ; Put the character into the video memory

然后您可能会在屏幕的开头看到一个 !。如果只想在光标位置打印,可以这样获取光标偏移量:

    mov dx,0x3D4       ; Tell the control I/O port to get the lower byte of
    mov al,0x0F        ; the cursor offset
    out dx,al
    mov dx,0x3D5       ; Switch to data I/O port
    in  al,dx          ; Get the cursor offset's lower byte

    mov dx,0x3D5       ; Tell the control I/O port to get the higher byte of
    mov al,0x0E        ; the cursor offset
    out dx,al
    mov dx,0x3D5       ; Switch to data I/O port
    in  al,dx          ; Get the higher byte

    imul ax,2           ; Because a character in video memory costs 2 bytes
                       ; (i.e character and attribute), we need to twice the cursor offset

In 32-bit protected mode, to increase your code's efficiency, you could use some high-level language like C to create the functions. This really increased the readability of the code.