0
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?

「手探りでCUI OS作成に挑む」問題解決篇 文字列表示がうまく行かない 

Last updated at Posted at 2025-06-01

「手探りでCUI OS作成に挑む」連載

この記事は「手探りでCUI OS作成に挑む」連載の一部です。
全体の目次は「手探りでCUI OS作成に挑む」連載目次を御覧下さい。

現象

以下のように表示される

TEST
. DAMMY
≡ 雪印

又は

- HALT
HALT
カーソル

本来は以下の筈

TEST
HALT

プログラム

ブートローダーから以下のプログラムを読み込む。
読み込み自体は問題ないように思う。

[org 0x7E00]
[bits 16]

;********************************************************************************
; システム初期化ブロック
;********************************************************************************
start:

; === セグメントレジスタ初期化 スタック設定===
    cli
    xor ax, ax
    mov ds, ax     ; データセグメントは 0 にしておく(test_string などの参照に対応)
    mov es, ax
    
    mov si, 0x7E00

    mov ax, 0x9000     ; 安全な場所にスタックを置く(0x9000:FFFF = 0x9FFFF)
    mov ss, ax
    mov sp, 0xFFFE     ; FFFEが望ましい(偶数)
    sti
    
    mov si, test_string
    call print_str
        
    mov si, hlt_msg
    call print_str
    
    cli
.loop:
    hlt
    jmp .loop

print_str:
    push ax
    push si
    mov ah, 0x0E    ; BIOSテレタイプ機能
.loop:
    lodsb           ; 次の文字をALにロード
    test al, al     ; ヌル文字チェック
    jz .done
    int 0x10        ; BIOS文字表示
    jmp .loop
.done:
    pop si
    pop ax
    ret

halt:
    cli
.loop:
    hlt
    jmp .loop
    

test_string      db 'TEST',0x0D,0x0A,0
hlt_msg          db 'HALT',0x0D,0x0A,0

DAMMY            db 'DAMMY',0x0D,0x0A,0


; パディング(512バイト×3のコードサイズを保証)
times 512 * 3-($-$$) db 0

ラベルの指定は正しいことを確認

文字列のオフセットを確認

hexdump -C load.bin > loadhexdump.txt
00000030  5e 58 c3 fa f4 eb fd 54  45 53 54 0d 0a 00 48 41  |^X.....TEST...HA|
00000040  4c 54 0d 0a 00 44 41 4d  4d 59 0d 0a 00 00 00 00  |LT...DAMMY......|

Tは0x37
Hは0x3E
から始まる。

逆アセンブル

ndisasm -b16 load.bin > loaddisasm.txt

mov si, test_string → mov si,0x7e37
mov si, hlt_msg → mov si,0x7e3e

ラベルのアドレス指定に問題は無い

変な現象

popa/pushaに変更しても正常に動かない
ax,siのみをpop/pushしても正常に動かないが、
ax,bx,siをpop/pushするか、ax,cx,siをpop/pushもしくはまともに動く。
CXでもBXでもよいことからレジスタそのものの問題ではなく、スタックに起因するものと思われる。

以下は正常に動作する例

print_str:
    push ax
    push bx
    push si
    mov ah, 0x0E
.loop:
    lodsb
    test al, al
    jz .done
    int 0x10
    jmp .loop
.done:
    pop si
    pop bx
    pop ax
    ret

halt:
    cli
.loop:
    hlt
    jmp .loop

割り込みが入りスタックがずれた可能性を考え、以下のように割り込みを禁止するも表示は不正なまま。

print_str:
    cli
    push ax
    push si
    sti
    
    mov ah, 0x0E
.loop:
    lodsb
    test al, al
    jz .done
    int 0x10
    jmp .loop
.done:
    cli
    pop si
    pop ax
    sti
    ret

原因はさっぱり分からない
一旦AX、BX、SIをPUSH/POPしたら動くのでこのまま開発を進める。
何日かして頭が整理されたら改めて調べる。

0
0
0

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
0
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?