操作系统的Boot-loader不起作用

Non*_*one 4 x86 kernel nasm osdev bootloader

我正在制作一个自定义操作系统.我有两个nasm文件:

boot.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
Run Code Online (Sandbox Code Playgroud)

start.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
Run Code Online (Sandbox Code Playgroud)

我使用以下命令将它们编译成.bin文件:

nasm boot.asm -f bin -o boot.bin
nasm start.asm -f bin -o start.bin
Run Code Online (Sandbox Code Playgroud)

然后使用以下命令将它们添加到软盘映像中:

dd if=boot.bin bs=512 of=MyOS.img count=1
dd if=start.bin bs=512 of=MyOS.img count=2
Run Code Online (Sandbox Code Playgroud)

当我从VirtualBox中的软盘映像启动时,它显示2个感叹号而不是一个,它甚至不在QEmu(Q.app)中启动.我是操作系统开发的新手,所以如果有人能告诉我我做错了什么并给我一些关于如何更好地设置我的操作系统的指示,那就太好了.

sta*_*ica 5

当然它打印出两个感叹号.我们来看看你的代码:

...
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
Run Code Online (Sandbox Code Playgroud)

注意:我添加了一些箭头来说明程序执行的进展情况.

!输出之后,前两行负责打印决赛Hello, World.这是通过调用您的PrintCharacter子程序实现的.(箭头12.)当PrintCharacter返回(箭头3)时,程序只是直接向前(箭头4)......并且下一行代码恰好是PrintCharacter再次开始.由于AL寄存器仍包含33(即ANSI代码!),因此打印另一个感叹号.

然后,执行再次进入RET,但这一次,因为你实际上没有CALL PrintCharacter,没有定义的地方返回,所以它返回到...一些未定义的地方,最有可能(箭头5).我想这是你的操作系统停止继续启动过程的瞬间.

结论:在你的代码打印之后Hello, World!,它应该做其他的事情(它应该至少停止),否则当你得到未定义的行为或挂起时不要感到惊讶......