我发现通常程序员会在引导程序的最开始修复寄存器(有时也会修复段寄存器),并且他们通常建议养成这种习惯。例如:
inc cx
dec bx
inc bp
dec di
xor ax, ax
我知道的是:BIOS在启动过程中会清除所有寄存器!在引导加载程序中初始化寄存器和段是一个好习惯吗?为什么?默认的寄存器、段和指针值是什么(可能与芯片组有关)?
我发现通常程序员会在引导程序的最开始修复寄存器(有时也会修复段寄存器),并且他们通常建议养成这种习惯。例如:
inc cx
dec bx
inc bp
dec di
xor ax, ax
由于你提到了分段寄存器的设置,以及你的代码似乎是16位代码,我将假设你正在讨论古老的IBM-PC启动加载程序(PC-BIOS),而不是(EFI/UEFI)。对于绝大多数已经制造过的设备,在PC-BIOS加载引导扇区并将控制权传递给它时,除了一个寄存器外,所有寄存器的状态都有可用的值。除了80年代和90年代的一些非标准(并且不是100%兼容的BIOS)之外,寄存器DL将包含BIOS引导的驱动器号码。这个值也被用于调用Int 13h磁盘服务例程。
SS:SP可能指向内存中的某个位置,但是从BIOS到BIOS它所指向的位置是不同的。如果你打算加载数据到内存中,应当自己设置栈指针(SS和SP)。否则你可能会无意中用数据覆盖栈。
有些人认为当控制权传递给你的引导程序时(通常通过),CS:IP总是设置为0x0000:0x7c00(CS=0x0000,IP=0x7c00)。不幸的是这并不能保证。一些启动加载程序已知使用0x07c0:0x0000,这也指向物理地址0x07c00(0x07c0<<4+0x0000)。这是因为不同的段:偏移寻址可以表示相同的物理地址(如0x07c00)。我写了一个Stackoverflow问题/答案,记录了一种情况,即假设CS始终为0x0000可能会导致根据环境的不同出现一些有趣的错误。
字符串指令(如CMPS和MOVS)中使用的方向标志(FLAGS寄存器中的DF)不应假定为特定方向。大多数代码使用向前移动(DF=0),但不能保证BIOS在跳转到引导加载程序之前设置了该方向。因此,应显式地使用CLD清除它以进行向前移动,或使用STD设置它以进行向后移动。