启动x86计算机时的默认寄存器和段值

时间:2017-04-12 02:41:46

标签: assembly x86 bootloader bios

我发现通常程序员在他们的第一行引导加载程序上修复寄存器(有时是段),并且通常会为此提供建议。例如:

inc cx
dec bx
inc bp
dec di
xor ax, ax

我想知道我所知道的是: BIOS在启动过程中清除所有寄存器

在引导加载程序中初始化寄存器和段是一个好习惯吗?如果是,默认寄存器,段和指针值是什么(可能依赖于芯片组)?

1 个答案:

答案 0 :(得分:4)

由于您提到了段寄存器的设置,并且您的代码似乎是16位代码,我将假设您正在讨论旧的IBM-PC引导加载程序(PC-BIOS)而不是(EFI / UEFI)。在大多数已经制造的设备的传统引导加载程序中,您可以假设很少。

当PC-BIOS从可用的引导设备加载引导扇区并将控制权转移给它时,所有寄存器的状态都有一个可用的值。除了80和90s的某些非标准(而非100%兼容的BIOS)之外,寄存器 DL 将包含BIOS引导的引导驱动器号。此值也是用于调用Int 13h disk service routines的值。

SS:SP 可能指向RAM中的某个位置,但这与BIOS不同。应该设置自己的堆栈指针( SS SP ),尤其是当您打算将数据加载到内存中时。除非您自己专门设置,否则您可能会无意中用数据覆盖堆栈。

有些人认为,当控制权转移到你的引导加载程序时, CS:IP 总是设置为0x0000:0x7c00(CS = 0x0000,IP = 0x7c00)(通常通过 FAR JMP )。不幸的是,这并不能保证。已知一些引导加载程序使用0x07c0:0x0000,其也指向物理地址0x07c00(0x07c0 <&lt; 4 + 0x0000)。这是因为不同的segment:offset addressing可以表示相同的物理地址(如0x07c00)。我写了一个Stackoverflow question/answer来捕捉这样一种情况:假设 CS 总是0x0000可能会导致一些有趣的错误,具体取决于环境。

用于字符串指令(如CMPSMOVS)的方向标志(FLAGS寄存器中的DF)不应被视为特定方向。大多数代码使用向前移动(DF = 0),但不能保证在跳转到引导加载程序之前BIOS是设置它的方向。因为那个人应该用CLD明确地清除它以进行向前移动,或者用STD设置它以便向后移动。

除上述 DL 寄存器外,您不应假设任何通用寄存器都已初始化。我经常看到假装它们为零的引导加载程序。几乎从来没有这种情况。

我的Stackoverflow General Bootloader Tips中讨论了很多这些事情。