x86 - 操作系统的引导加载程序不起作用

标签 x86 kernel nasm bootloader osdev

我正在制作自定义操作系统。我有两个 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 中的软盘镜像启动时,它显示 2 个感叹号而不是一个,并且它甚至无法在 QEmu (Q.app) 中启动。我是操作系统开发的新手,所以如果有人能告诉我我做错了什么并给我一些关于如何更好地设置我的操作系统的指示,那就太好了。

最佳答案

当然,它会打印两个感叹号。让我们看看你的代码:

...
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

Note: I added some arrows that illustrate how program execution proceeds.



前两行负责打印最后的!在您已经输出 Hello, World 之后.这是通过调用您的 PrintCharacter 来实现的。子程序。 (箭头 12。)当 PrintCharacter返回(箭头 3 ),您的程序只是继续向前(箭头 4 )...而下一行代码恰好是 PrintCharacter 的开头再次。自 AL register 仍然包含 33(即 ! 的 ANSI 代码),打印另一个感叹号。

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

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

关于x86 - 操作系统的引导加载程序不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3285721/

相关文章:

c - x86 硬件中断不适用于 qemu

assembly - 在 assembly 中进入和离开?

macos - xnu内核中防止文件直接内存读取

c++ - 用宏确定GCC编译器

assembly - NASM 中的 equ 和 db 有什么区别?

x86 - 使用 SIMD 提取位

x86 - vextracti128 和 vextractf128 有什么区别?

linux - 调度程序中的 sched_feat 宏是什么意思

linux - 如何在 Linux 中跟踪系统调用?

python - 无法访问传递给 NASM 64 位 DLL 的数组指针