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作成に挑む」問題解決篇 スタックの変化を観察

Posted at

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

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

目的

スタックが壊れ、土日2日間掛けても解決しなかった為、初めから書き直すことにした。
もうはまらないように文字表示をした際にスタックが正常に動くか検証する。
一人でやっていると結構精神的に参るので頑張った記録を載せる。
昨日はまった時はレジスタの値を表示するコードすらまともに動かなかったが今日コードを書き直して確認したところではスタックは崩れていないことが確認できた。

書き直したコード

load.asm
load.asm
[org 0x7E00]
[bits 16]

start:

    ; セグメント及びスタックの初期化
    cli
    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ax,2000
    mov ss,ax
    mov sp,0xFFFE
    sti

    ; 画面モードをテキストモードに設定
    mov ah, 0x00
    mov al, 0x03
    int 0x10

    mov si, message1
    call print_str

    mov si, message2
    call print_str
    
    mov si, message3
    call print_str
    
    mov si, message4
    call print_str

done:
    cli
hang:
    hlt
    jmp hang


; 文字列表示関数
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

message1 db 'message1', 0x0D, 0x0A, 0
message2 db 'message2', 0x0D, 0x0A, 0
message3 db 'message3', 0x0D, 0x0A, 0
message4 db 'message4', 0x0D, 0x0A, 0

times 512 - ($ - $$) db 0

プログラム中で表示する

QEMUでは以下の命令がうまく効かなかったため、SSは断念してSPの値のみ観察する

    mov ax, ss
    call print_hex16
load.asm
load.asm
[org 0x7E00]
[bits 16]

start:

    ; セグメント及びスタックの初期化
    cli
    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ax,2000
    mov ss,ax
    mov sp,0xFFFE
    sti

    ; 画面モードをテキストモードに設定
    mov ah, 0x00
    mov al, 0x03
    int 0x10

    mov ax, sp
    call print_hex16

    mov si, message1
    call print_str

    mov ax, sp
    call print_hex16

    mov si, message2
    call print_str
    
    mov ax, sp
    call print_hex16

    mov si, message3
    call print_str

    mov ax, sp
    call print_hex16
    
    mov si, message4
    call print_str

done:
    cli
hang:
    hlt
    jmp hang


; 文字列表示関数
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

%include "debug.asm"

message1 db 'message1', 0x0D, 0x0A, 0
message2 db 'message2', 0x0D, 0x0A, 0
message3 db 'message3', 0x0D, 0x0A, 0
message4 db 'message4', 0x0D, 0x0A, 0

times 512 - ($ - $$) db 0
debug.asm
debug.asm
; 使用例:レジスタ表示
;    mov ax, si       ; SIの値をAXにコピー
;    call print_hex16

;---------------------------------------
; AXの値を16進数で表示する (例: "3F20")
;---------------------------------------
print_hex16:
    pusha
    mov cx, 4         ; 4桁出力
.hex_loop:
    rol ax, 4         ; 上位4bitをALに持ってくる
    mov bl, al
    and bl, 0x0F
    call print_hex_digit
    loop .hex_loop
    
    mov ah, 0x0E
    mov al, 0x0D    ; CR(キャリッジリターン)
    int 0x10
    mov al, 0x0A    ; LF(ラインフィード)
    int 0x10

    popa
    ret

;---------------------------------------
; ALの下位4bitを16進文字に変換して出力
; 入力: BL = 0〜15
;---------------------------------------
print_hex_digit:
    pusha
    cmp bl, 10
    jl .digit
    add bl, 'A' - 10
    jmp .output
.digit:
    add bl, '0'
.output:
    mov al, bl
    mov ah, 0x0E
    int 0x10
    popa
    ret

678a203586ef9da170215b90013875e.png

QEMU+は断念

以下ので順で逆アセンブルをしたが、何度やっても16ビットとして認識されず、EAXのようなレジスタが表示されたのでQEMUを使うことは断念。
32、64ビットモードなら以下の手順でうまく行くと思う。

  1. QEMUをこのように起動
qemu-system-i386 -fda testdisk.img -s -S
  1. 別の端末で gdb
gdb
set architecture i8086
target remote localhost:1234 # 接続する
set disassembly-flavor intel # インテル記法へ切り替え
b *0x7e00                    # ブレークポイントを貼る
c                            # ブレークポイントまで進める
x/20i 0x7e00                 # 0x7e00から逆アセンブル

明らかに16ビットモードではありえないコードに変換されてしまう。

   …
   0x7e01:	xor    eax,eax
   0x7e03:	mov    ds,eax
   0x7e05:	mov    es,eax
   0x7e07:	mov    eax,0xd08e07d0
   ……

Bochs+も断念

対応していない??

ubuntu@ubuntu:~/kaihatsu/test3$ bochs -f bochsrc
00000000000i[      ] LTDL_LIBRARY_PATH not set. using compile time default '/usr/lib/x86_64-linux-gnu/bochs/plugins'
========================================================================
                        Bochs x86 Emulator 2.7
              Built from SVN snapshot on August  1, 2021
                Timestamp: Sun Aug  1 10:07:00 CEST 2021
========================================================================
00000000000i[      ] BXSHARE not set. using compile time default '/usr/share/bochs'
00000000000i[      ] lt_dlhandle is 0x5c0e388b0110
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?