4

カスタムオペレーティングシステムを作成しています。2 つの nasm ファイルがあります。

ブート.asm:

[BITS 16]   ;tell the assembler that its a 16 bit code
[ORG 0x7C00]    ;Origin, tell the assembler that where the code will
;be in memory after it is been loaded

INT 0x13

JMP $       ;infinite loop

TIMES 510 - ($ - $$) db 0   ;fill the rest of sector with 0
DW 0xAA55           ; add boot signature

開始.asm:

[BITS 16]
MOV AL, 72
CALL PrintCharacter
MOV AL, 101
CALL PrintCharacter
MOV AL, 108
CALL PrintCharacter
MOV AL, 108
CALL PrintCharacter
MOV AL, 111
CALL PrintCharacter
MOV AL, 44
CALL PrintCharacter
MOV AL, 32
CALL PrintCharacter

MOV AL, 87
CALL PrintCharacter
MOV AL, 111
CALL PrintCharacter
MOV AL, 114
CALL PrintCharacter
MOV AL, 108
CALL PrintCharacter
MOV AL, 100
CALL PrintCharacter
MOV AL, 33
CALL PrintCharacter

PrintCharacter: 
MOV AH, 0x0E
MOV BH, 0x00
MOV BL, 0x07
INT 0x10
RET

TIMES 512 - ($ - $$) db 0

次のコマンドを使用して、それらを .bin ファイルにコンパイルします。

nasm boot.asm -f bin -o boot.bin
nasm start.asm -f bin -o start.bin

次に、次のコマンドを使用して、それらをフロッピー イメージに追加します。

dd if=boot.bin bs=512 of=MyOS.img count=1
dd if=start.bin bs=512 of=MyOS.img count=2

VirtualBox のフロッピー イメージから起動すると、感嘆符が 1 つではなく 2 つ表示され、QEmu (Q.app) で起動することさえできません。私はオペレーティング システムの開発に慣れていないので、どこが間違っていたのか、OS をより適切にセットアップする方法について誰かが教えてくれたらうれしいです。

4

2 に答える 2

5

もちろん、2 つの感嘆符が出力されます。あなたのコードを見てみましょう:

...
MOV AL, 33
CALL PrintCharacter    ;   |1
                       ;   |          ^     |4
PrintCharacter:        ;   v    |2    |     |
MOV AH, 0x0E           ;        |     |     |
MOV BH, 0x00           ;        |     |     |
MOV BL, 0x07           ;        |     |     |
INT 0x10               ;        |     |     |     5
RET                    ;        v     |3    v     ----> off to la-la land

注: プログラムの実行がどのように進行するかを示すいくつかの矢印を追加しました。

最初の 2 行は、既に出力した後の最終的な出力を担当し!ますHello, WorldPrintCharacterこれは、サブプロシージャーへの呼び出しによって実現されます。(矢印12.) PrintCharacter(矢印) を返す3と、プログラムは単純にまっすぐ進みます (矢印4)...そして、コードの次の行はたまたまPrintCharacter再び始まります。ALレジスタにはまだ 33 (つまり の ANSI コード) が含まれているため、!別の感嘆符が出力されます。

次に、実行は再び に到達しRETますが、今回は、実際CALL PrintCharacterには に戻らなかったため、戻る場所が定義されていないため、戻ります... 未定義の場所、おそらく (矢印5)。それは、OS が起動プロセスの続行を停止する瞬間だと思います。

結論:コードが出力された後、Hello, World!何か他のことを行う必要があります(少なくとも停止する必要があります)。そうしないと、未定義の動作やハングアップが発生しても驚かないでください...

于 2010-07-19T23:13:34.360 に答える
1

VirtualBox がどのようにコードを起動しているかはわかりませんが、ディスク イメージにバイナリを間違った方法で設定しているため、qemu が起動していないことは確かです。ディスク イメージで 'dd' を使用している場合は、次のように、ディスクが切り捨てられないようにオプションを渡す必要があります。

dd if=boot.bin of=MyOS.img bs=512 count=1 conv=notrunc status=noxfer
dd if=start.bin of=MyOS.img bs=512 count=1 conv=notrunc seek=1 status=noxfer

conv=notrunc は 'dd' に、ディスクを切り詰めてはならないことを伝えます。つまり、ディスクを削除してバイナリで上書きします。 0 から始まります)。

私が言っていることを確認するには、1MB のディスク イメージを作成してみて、使用していたコマンド (つまり dd) を使用すると、ディスク イメージがバイナリのコピーに縮小されることがわかります。

したがって、最後に、ディスク イメージとして start.bin を使用して qemu を呼び出します (MyOS.img は、最後の「dd」コマンドの後にそのコピーになります)。また、start の最後にブート署名を使用していないためです。 bin の場合、qemu BIOS はディスクが起動可能であると認識しません。

于 2011-11-01T03:18:23.237 に答える