Assembly mbr中的堆栈初始化

Assembly mbr中的堆栈初始化,assembly,x86,mbr,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:

假设我正在编写自己的
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\u堆栈
放在哪里?我不会告诉链接器脚本关于它的任何事情。但是如果我这样做,那么输出文件的大小超过512字节,我不能将其用作
mbr
。为什么此C堆栈正常工作后?

如果使用ld的
-M
选项生成映射文件,您将看到它将地址0分配给
。引导\u堆栈

名称原点长度属性
*默认值*0x0000000000000xFFFFFFFFFFFF
链接器脚本和内存映射
0x0000000000007c00..=0x7c00
.text 0x0000000000007c00 0x9
*(.文本)
.text 0x0000000000007c00 0x9 t95.o
0x0000000000007c00\u启动
.sig 0x0000000000007c09 0x2加载地址0x0000000000007dfe
0x0000000000007c09 0x2短0xaa55
加载t95.o
输出(a.out二进制)
.数据0x0000000000007c0b 0x0加载地址0x0000000000007e00
.数据0x0000000000007c0b 0x0 t95.o
.bss 0x0000000000007c0b 0x0加载地址0x0000000000007e00
.bss 0x0000000000007c0b 0x0 t95.o
.bootstrap_堆栈
0x0000000000000000 0x4000
.bootstrap_堆栈
0x0000000000000000 0x4000 t95.o
您可以通过反汇编生成的二进制文件来验证这一点:

$objdump-b binary-mi8086——调整vma=0x7c00-D a.out
...
7c00:fa cli
7c01:66 bc 00 40 00 mov$0x4000,%esp
7c07:eb fe jmp 0x7c07
...
7dfd:00 55 aa添加%dl,-0x56(%di)
我建议使用一个您知道是安全的固定常量来加载SP(而不是ESP),而不是使用不会实际出现在生成的输出中的部分。您还需要同时加载SS,因为堆栈的实际地址是SS:SP,也就是说,它位于
SS*16+SP
。例如:

\u开始:
异或%ax,%ax
移动%ax,%ds
移动%ax,%es
移动%ax,%ss
mov$0x7c00,%sp#堆栈从引导加载程序开始向下增长

谢谢你的精彩回答,这正是我想要的,甚至更多。顺便问一下,你能解释一下,我是在我的代码
堆栈底部写的吗:
部分位于地址0(as
.bootstrap\u stack
),而
堆栈顶部
位于地址
0x4000
(as
.bootstrap\u stack
+它的大小)。从
0x7c00
开始增加堆栈是否安全。它不会包含一些有用的信息吗?@Dima堆栈向较低的地址增长。堆栈上推送的第一个字将位于0000:7bfc,下一个字将位于0000:7bfc。这些地址没有被任何人使用。从0000:0500到0000:7BF的所有内容都可以免费使用。我不确定这是否是您要问的,但是,是的,
stack\u-bottom
为0,
stack\u-top
为0x4000。