Moh*_*HME 4 x86 assembly bios bootloader
我发现通常程序员在启动加载程序的第一行就对寄存器(有时是段)进行修正,并且他们通常会为此建议。例如:
inc cx
dec bx
inc bp
dec di
xor ax, ax
Run Code Online (Sandbox Code Playgroud)
我不知道我知道的是:BIOS在引导过程中清除了所有寄存器。
在引导加载程序中初始化寄存器和段是个好习惯吗?如果是,默认寄存器,段和指针值是什么(可能取决于芯片组)?
由于您提到了段寄存器的设置,并且您的代码似乎是16位代码,因此我假设您正在讨论的是传统的IBM-PC引导加载程序(PC-BIOS),而不是(EFI / UEFI)。对于大多数已制造的设备,传统的引导加载程序几乎没有什么可以假设的。
等到PC-BIOS从可用的引导设备加载引导扇区并将所有寄存器的状态转移到该引导扇区时,其中一个寄存器才具有可用值。除了80年代和90年代的一些非标准(不是100%兼容的BIOS)外,寄存器DL将包含BIOS引导的引导驱动器号。此值也是用于调用Int 13h磁盘服务例程的值。
SS:SP可能指向RAM中的某个位置,但是每个BIOS的位置都不相同。应该设置自己的堆栈指针(SS和SP),特别是如果您打算将数据加载到内存中。除非您专门进行设置,否则您可能会无意间用数据覆盖堆栈。
有人认为,将控制权转移到引导加载程序(通常通过FAR JMP)时,CS:IP始终设置为0x0000:0x7c00(CS = 0x0000,IP = 0x7c00 )。不幸的是,这不能保证。已知某些引导程序使用0x07c0:0x0000,它也指向物理地址0x07c00(0x07c0 << 4 + 0x0000)。这是因为不同的segment:offset寻址可以表示相同的物理地址(如0x07c00)。我写了一个Stackoverflow问题/答案,其中捕获了假设CS始终为0x0000 的情况,这可能会导致一些有趣的错误,具体取决于环境。
不应将用于字符串指令(如CMPS和MOVS)的方向标志(FLAGS寄存器中的DF )视为特定方向。大多数代码使用向前移动(DF = 0),但是不能保证这是BIOS跳转到引导加载程序之前设置的方向。因此,应使用CLD明确清除它以进行向前移动,或使用STD对其进行设置以进行向后移动。
除了前面提到的DL寄存器,您不应该假设所有通用寄存器都已初始化。我经常看到引导加载程序假定它们为零。几乎从来没有这样。
我的Stackoverflow 常规Bootloader技巧中讨论了许多这些内容。