mbr中的堆栈初始化

时间:2015-12-06 12:17:45

标签: assembly x86 mbr

假设我正在编写自己的mbr部分,并且我想在其中运行一些C代码。为此,我首先需要初始化堆栈,然后调用C代码。我以这样的方式做到了

boot.S档案:

.code16

.section .bootstrap_stack #initializing stack here
stack_bottom:
.skip 16384
stack_top:

.text
.global _start
_start:
    cli
    movl $stack_top, %esp
    call kmain
loop:
    jmp loop

在我的C代码中,我有函数kmain

我的linker.ld文件如下所示:

OUTPUT_FORMAT(binary)
OUTPUT_ARCH(i8086)
ENTRY(_start)

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

所以问题是内存部分.bootstrap_stack放在哪里?我不会告诉链接器脚本有关它的任何信息。但是,如果我这样做,那么输出文件的大小超过512字节,我不能将其用作mbr。为什么在此C堆栈正常工作后?

1 个答案:

答案 0 :(得分:2)

如果你使用ld的-M选项以便它生成一个地图文件,你会看到它将地址0分配给.bootstrap_stack

Name             Origin             Length             Attributes
*default*        0x0000000000000000 0xffffffffffffffff

Linker script and memory map

                0x0000000000007c00                . = 0x7c00

.text           0x0000000000007c00        0x9
 *(.text)
 .text          0x0000000000007c00        0x9 t95.o
                0x0000000000007c00                _start

.sig            0x0000000000007c09        0x2 load address 0x0000000000007dfe
                0x0000000000007c09        0x2 SHORT 0xaa55
LOAD t95.o
OUTPUT(a.out binary)

.data           0x0000000000007c0b        0x0 load address 0x0000000000007e00
 .data          0x0000000000007c0b        0x0 t95.o

.bss            0x0000000000007c0b        0x0 load address 0x0000000000007e00
 .bss           0x0000000000007c0b        0x0 t95.o

.bootstrap_stack
                0x0000000000000000     0x4000
 .bootstrap_stack
                0x0000000000000000     0x4000 t95.o

您可以通过反汇编生成的二进制文件来验证这一点:

$ objdump -b binary -m i8086 --adjust-vma=0x7c00 -D a.out
...
    7c00:       fa                      cli
    7c01:       66 bc 00 40 00 00       mov    $0x4000,%esp
    7c07:       eb fe                   jmp    0x7c07
        ...
    7dfd:       00 55 aa                add    %dl,-0x56(%di)

我建议您使用固定常数加载SP(而不是ESP),而不是使用实际出现在生成输出中的部分。您还需要同时加载SS,因为堆栈的实际地址是SS:SP,即它位于SS * 16 + SP。例如:

_start:
     xor %ax, %ax
     mov %ax, %ds
     mov %ax, %es
     mov %ax, %ss
     mov $0x7c00, %sp  # stack grows downwards from start of boot loader