3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

自分でOSを1から作ってみるAdvent Calendar 2024

Day 5

VRAMを使用して文字表示する

Last updated at Posted at 2024-12-04

自分でOSを1から作ってみる Advent Calendar 2024の5日目です。

今日の目標

この前作成したブートセクタはテキストを表示させましたが、BIOSを使って表示させました。なので今回はとりあえずBIOSを使用せずVRAMを使って「Hello,World!」を表示させようと思います。

VRAMについて

VRAMは通常のRAMと似ているのですが、映像データの処理に特化しており、CPUとGPUのどちらからでもアクセスできるようになっています。詳しいことは調べてください。

制作

まずVRAMを使って「Hello,World!」を表示させるコードを載せてしまいます。解説も後に載っています。

boot.asm
[BITS 16]
[ORG 0x7C00]

start:
    ; ビデオメモリの先頭アドレスを設定 (0xB8000)
    mov ax, 0xB800
    mov es, ax          ; ESをビデオメモリのセグメントアドレスに設定
    mov di, 0           ; DIを0に初期化(ビデオメモリのオフセット)

    ; 表示する文字列のアドレスをSIに設定
    mov si, message

print_string:
    mov al, [si]        ; SIが指す文字をALに読み込む
    cmp al, 0           ; 文字がnull(0)かチェック
    je done             ; nullなら終了
    mov [es:di], al     ; ビデオメモリに文字を書き込み
    mov byte [es:di+1], 0x0F ; 属性(白文字、黒背景)を設定
    add di, 2           ; 次の文字位置に移動
    inc si              ; 次の文字へ
    jmp print_string    ; 繰り返す

done:
    ; 無限ループで終了
    cli                 ; 割り込み禁止
hang:
    hlt
    jmp hang

; 表示するメッセージ
message db "Hello, World!", 0

times 510-($-$$) db 0    ; パディングを加えて512バイトに調整
dw 0xAA55                ; ブートセクタシグネチャ

実行方法は前の記事を参照してください。

コードの解説

今回新出のコードのみ説明しておこうと思います

ビデオメモリの設定

boot.asm
mov ax, 0xB800
mov es, ax
mov di, 0

mov ax, 0xB800 は、テキストモードのビデオメモリのセグメントアドレス(0xB800)をAXレジスタに設定します。
mov es, ax により、ビデオメモリのセグメントアドレスを ES レジスタにロードします。
mov di, 0 により、ビデオメモリのオフセットが0に初期化されます。

メッセージの表示

boot.asm
print_string:
    mov al, [si]
    cmp al, 0
    je done
    mov [es:di], al
    mov byte [es:di+1], 0x0F
    add di, 2
    inc si
    jmp print_string

print_string ラベルから始まるループで、メッセージを1文字ずつVRAMに書き込みます。
mov al, [si] で SI レジスタが指す文字を AL レジスタにロードします。(mov si, messageで設定した値)
cmp al, 0je done により、文字がNULL文字(終了文字)であれば done にジャンプし、処理を終了します。
mov [es:di], al により、ビデオメモリの ES:DI アドレスに文字を表示します。
mov byte [es:di+1], 0x0F で、文字の属性(白文字、黒背景)を設定します。
add di, 2 で次の文字位置に移動します(VRAMは1文字2バイト幅)。
inc si で次の文字に進みます。
jmp print_string でループを続けます。

終わりに

今回のブートセクタはカーネルをロードしたりはしていないのでまだOSという感じはしません。なのでそろそろカーネルのロードとかをしたいと思うのですが、自分でブートローダを作っても大変だし不便だしでメリットがないのでブートローダに関しては既成のものを使用しようと思います。もしかしたら最後の方で自分でブートローダを作ってみるかもしれません。

3
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?