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

tir*_*irz 7 c c++ assembly gcc bootloader

我尝试创建一个打印"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

boot.ld

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

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");
}
Run Code Online (Sandbox Code Playgroud)

输出:

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

输出:

TestBootLoader2

为什么输出是空的?

我的功能有什么问题?

我忘了什么?

谢谢你的帮助.

小智 2

感谢@MichaelPetch回答。

源代码:

启动文件

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

引导程序

另外这里: http: //pastebin.com/6NV3UMjE

asm(".code16gcc");
__asm__("jmpl $0x0000, $main\n");

void cout(const char* str);

void main()
{
    __asm__ __volatile__ ("xor %ax, %ax\n");
    __asm__ __volatile__ ("mov %ax, %ds\n");
    cout("Hello World");
    __asm__ __volatile__("cli\n");
    __asm__ __volatile__("hlt\n");
}

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

编译:

gcc -c -g -O0 -m32 -ffreestand -Wall -Werror boot.cpp -o boot.o

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

objcopy -O 二进制 boot.elf boot.bin

dd if=boot.bin of=floppy.img conv=notrunc

输出:

输出

  • 这是一个丑陋脆弱的黑客行为,并且“将”在未来造成巨大的问题。在继续之前,请阅读 [OSDev Wiki](http://wiki.osdev.org/) 并了解提供给您的解决方案意味着什么。这都是为了防止您遇到人们在做此类事情时已经遇到的几乎无法调试的问题。 (2认同)