1

非常に単純なブート プログラムを作成しようとしていますが、デバッグに問題があります。QEMU を使用して、次のように GDB に接続しています。

(gdb) set architecture i8086
(gdb) target remote localhost:1234
(gdb) break *0x7C00
(gdb) layout asm
(gdb) continue

...これはうまく機能し、コードの最初のいくつかの命令に到達できます。siただし、Iまたはni特定の命令ですぐにint、このパターンが GDB アセンブリ ビューに表示されます。

0x8669  add    %al,(%bx,%si)                                               │
0x866b  add    %al,(%bx,%si)                                               │
0x866d  add    %al,(%bx,%si)                                               │
<ad nauseam>

これは停止したり、期待した場所に戻ったりするようには見えません。ここに私のアセンブリコードがあります:

stage1.S

#include "stage1.h"

.text
.code16
.org STAGE1_START

.globl _start
_start:
    JMP     main
    NOP

write:
    LODSB
    OR      %al, %al
    JZ      write_exit

    MOV     $0xE, %ah
    MOV     $0x9, %bx
    INT     $0x10
    JMP     write   

    write_exit:
        RET

video_setup:
    MOV     $0x0, %ah
    MOV     $0x3, %al
    INT     $0x10 /* This causes the problem. */
    RET 

LoadMsg:    .asciz "Loading second stage..."
BootDrive:  .byte
main:
    MOV     %dl, STAGE1_ABS_POS(BootDrive)
    CALL        video_setup
    LEA     STAGE1_ABS_POS(LoadMsg), %si
    CALL        write
    HLT

/* Fill file to 512 bytes, regardless. */
.fill           STAGE1_BOOTLOADER_SIZE - (. - _start)

/* BIOS magic. */
.word           STAGE1_BOOTLOADER_SIG

stage1.h

#ifndef STAGE_1_H
#define STAGE_1_H

#define STAGE1_START            0x0
#define STAGE1_BOOTLOADER_OFFSET    0x7C00
#define STAGE1_BOOTLOADER_SIG       0xAA55

#define STAGE1_BOOTLOADER_SIZE      0x1FE

#define STAGE1_ABS_POS(X) (X-_start+STAGE1_BOOTLOADER_OFFSET)

#endif

QEMU でデバッグ オプションを使用せずにプログラムを実行すると、プログラムが正常に動作するため、コードがメモリ内のランダムな場所にジャンプしないことはわかっています。

私は何を間違っていますか?一般的に、私のコードに対する批判も大歓迎です。

4

1 に答える 1