2017-04-12 85 views
4

我发现通常程序员会在它们的第一行引导程序中注册(有时是段),他们通常会为此提供建议。例如:启动x86机器时的默认寄存器和段值

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

我不知道,我知道的是:BIOS引导过程中清除所有寄存器

初始化引导加载程序中的寄存器和段是否是一种好习惯?如果是的话,什么是默认寄存器,段和指针值(也许芯片组相关)?

+2

英特尔文档确实指明了CPU启动时每个寄存器包含的值。但是在BIOS交给引导加载程序之后,你是在问状态,所以谁知道...... – Nayuki

+0

谢谢@Nayuki。你是对的。 –

+6

当你到达执行引导程序的时候,你只能假设一件事情(除了一些20世纪80年代的时代不兼容的计算机)。这是由BIOS启动的驱动器号码在_DL_寄存器中,除此之外,您不应该对标志的状态,段寄存器的状态以及任何通用寄存器的状态做任何假设。 –

回答

3

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

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

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

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

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

除了前面提到的DL寄存器,您不应该假定任何通用寄存器都已初始化。我经常看到假设他们为零的引导加载程序。这几乎从未如此。

很多这些东西在我的Stackoverflow General Bootloader Tips讨论。

+1

谢谢亲爱的。顺便说一下,我添加了BIOS到标签。 –