SP用于引导过程应该使用哪个值?

时间:2012-05-15 10:28:59

标签: assembly x86 boot bootloader

BIOS中的引导序列会将它找到的第一个有效MBR加载到地址0x7C00的计算机物理内存中。

启动过程中SP应该使用哪个值?

org 7c00h      ; set location counter.
mov ax, XXX    ; What is XXX?
mov sp, ax
; Now PUSH an POP are safe

2 个答案:

答案 0 :(得分:4)

<00> 0000:0500至0007:FFFF保证免费使用。正确的初始化如下所示:

org 0x0600
...

cli
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00

; relocate itself
mov si, sp
mov di, 0x0600
mov cx, 256
rep movsw

; make sure we'are at 0000:0600+x
jmp 0:.reloc
.reloc:
push 2
popf    ; flags with all off

我使用7C00,堆栈向下,代码向上。您可以将7C00替换为上述任何有效范围,只需确保不会覆盖您自己的代码/数据。

顺便说一下,大多数MBR会按照传统将自己重新安置到0000:0600,并将VBR链式加载到7C00。

另请注意jmp .reloc,一些错误的BIOS启动MBR与07C0:0000,所以jmp确保CS = 0

答案 1 :(得分:3)

SS:SP的任何值,以便为代码 AND 中断服务例程提供足够的堆栈空间是可以的。

当然,您的堆栈不应与任何代码或其他数据冲突,也不应碰到ROM或内存映射设备地址范围。

BIOS不保证引导扇区将接收SS:SP。因此,仅更改SP是不对的。

您可以这样做(如果此位置没有您的任何代码或数据):

...
mov ax, 0
mov ss, ax
mov sp, ax
...

这会将SS:SP设置为0:0。不要惊慌。下一次推送将首先将SP从0递减到0xFFFE并写入0:0xFFFE,而不是0:0。

这将在引导扇区结束和最大堆栈指针地址之间提供0x10000 - (0x7c00 + 0x200)= 33280字节的空间。这是充足的堆栈空间。

另请注意,更改SSSP时,您必须禁用中断或首先更改SS,然后在紧随其后更改SP指令(如上所示)。

或者您可以使用LSS SP, ...指令,但它将远地址的地址作为参数,这意味着您的新SS:SP值首先需要位于内存中的某个位置。

另一种更改SSSP的方法是使用PUSHRETF