gpt4 book ai didi

c++ - 编写一个简单的 Bootloader HelloWorld - 错误函数打印字符串

转载 作者:可可西里 更新时间:2023-11-01 18:37:40 27 4
gpt4 key购买 nike

我尝试创建一个打印“hello world”的简单引导加载程序。

当我调用一个只打印“hello world”的函数时我可以做到这一点,但是当我调用一个函数来打印特定字符串时,什么也没有发生。

为此,我使用了两个文件。第一个是 boot.ld,第二个是 boot.cpp(它也可以在 C 中使用 boot.c)。

首先,我从我的终端创建软盘:

dd if=/dev/zero of=floppy.img bs=512 count=2880

其次,我编译代码(boot.cpp 和 boot.ld):

gcc -c -g -Os -m64 -ffreestanding -Wall -Werror boot.cpp -o boot.o

ld -static -Tboot.ld -nostdlib --nmagic -o boot.elf boot.o

objcopy -O binary boot.elf boot.bin

最后,我将 boot.bin 添加到 floppy.img 中:

dd if=boot.bin of=floppy.img

现在我们只需要从 VirtualBox 的存储面板添加软盘并启动我们的虚拟机。

FloppyImage

源代码

来自:http://www.codeproject.com/Articles/664165/Writing-a-boot-loader-in-Assembly-and-C-Part

启动.ld

ENTRY(main);
SECTIONS
{
. = 0x7C00;
.text : AT(0x7C00)
{
*(.text);
}
.sig : AT(0x7DFE)
{
SHORT(0xaa55);
}
}

boot.cpp(或 boot.c)

void cout();

void main()
{
cout();
}

void cout()
{
__asm__ __volatile__("movb $'h' , %al\n");
__asm__ __volatile__("movb $0x0e, %ah\n");
__asm__ __volatile__("int $0x10\n");

__asm__ __volatile__("movb $'e' , %al\n");
__asm__ __volatile__("movb $0x0e, %ah\n");
__asm__ __volatile__("int $0x10\n");

__asm__ __volatile__("movb $'l' , %al\n");
__asm__ __volatile__("movb $0x0e, %ah\n");
__asm__ __volatile__("int $0x10\n");

__asm__ __volatile__("movb $'l' , %al\n");
__asm__ __volatile__("movb $0x0e, %ah\n");
__asm__ __volatile__("int $0x10\n");

__asm__ __volatile__("movb $'o' , %al\n");
__asm__ __volatile__("movb $0x0e, %ah\n");
__asm__ __volatile__("int $0x10\n");

__asm__ __volatile__("movb $' ' , %al\n");
__asm__ __volatile__("movb $0x0e, %ah\n");
__asm__ __volatile__("int $0x10\n");

__asm__ __volatile__("movb $'w' , %al\n");
__asm__ __volatile__("movb $0x0e, %ah\n");
__asm__ __volatile__("int $0x10\n");

__asm__ __volatile__("movb $'o' , %al\n");
__asm__ __volatile__("movb $0x0e, %ah\n");
__asm__ __volatile__("int $0x10\n");

__asm__ __volatile__("movb $'r' , %al\n");
__asm__ __volatile__("movb $0x0e, %ah\n");
__asm__ __volatile__("int $0x10\n");

__asm__ __volatile__("movb $'l' , %al\n");
__asm__ __volatile__("movb $0x0e, %ah\n");
__asm__ __volatile__("int $0x10\n");

__asm__ __volatile__("movb $'d' , %al\n");
__asm__ __volatile__("movb $0x0e, %ah\n");
__asm__ __volatile__("int $0x10\n");
}

输出:

TestBootLoader1

有漏洞的源代码

boot.cpp(或 boot.c)

void cout(const char* str);

void main()
{
cout("hello world");
}

void cout(const char* str)
{
while(*str)
{
__asm__ __volatile__ ("int $0x10" : : "a"(0x0e00 | *str), "b"(0x0007));
++str;
}
}

输出:

TestBootLoader2

为什么输出是空的?

我的功能有什么问题?

我忘记了什么?

感谢您的帮助。

最佳答案

在我的交叉编译器 (i686-elf-gcc (GCC) 4.9.2) 上,后面的代码生成以下 (dis) 程序集:

    boot.o:     file format elf32-i386


Disassembly of section .text:

00000000 <cout>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 53 push %ebx
4: bb 07 00 00 00 mov $0x7,%ebx
9: 8b 55 08 mov 0x8(%ebp),%edx
c: 0f be 02 movsbl (%edx),%eax
f: 84 c0 test %al,%al
11: 74 08 je 1b <cout+0x1b>
13: 80 cc 0e or $0xe,%ah
16: cd 10 int $0x10
18: 42 inc %edx
19: eb f1 jmp c <cout+0xc>
1b: 5b pop %ebx
1c: 5d pop %ebp
1d: c3 ret

我很想知道您是否将 GCC(一种非 16 位兼容的编译器)与 16 位内容(BIOS 中断)一起使用。如果您要编写 16 位代码,请使用完整的汇编代码! GCC 只会把它搞砸,因为它生成的 32 位代码将在 16 位模式下运行。如果你想直接上C/C++,那么你要写的可能不是bootloader,而是一个kernel。 .在这种(常见)情况下,请阅读 the unquestionable sacred ritual to initiate you into OSDev .你的第一个例子成功只是运气,任何微小的变化都可能破坏一切,甚至导致 the mythical horrifying triple fault, nightmares of kernel panics themselves .

无论如何,你最好直接写入 VGA DMA 内存而不是使用 BIOS 调用(你需要先访问 protected mode,然后访问 setup the VGA hardware and modes (GRUB 会为您完成此操作,但您正在创建引导加载程序,不是吗?)):

void PrintString(const char *str) {
uint16_t *vga = (uint16_t*)0xB8000;

for(; *str != '\0'; str++, vga++)
*vga = ((uint16_t)0x07 << 8) | *str; // Light grey on a black background, nice!
}

顺便说一句,您可能会发现 the OSDev community, wiki, andforums很有用。而且,如评论中所示,您应该为 real mode 使用 .code16代码,并且您的链接文章已经显示了它的年龄。

关于c++ - 编写一个简单的 Bootloader HelloWorld - 错误函数打印字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32931063/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com