操作系统代码最开头的512字节的数据,从硬盘的启动区先是被移动到了内存的0x7c00处,然后又立刻被移动到了0x90000处,并且跳转到此处再稍稍偏移go这个标签所代表的偏移地址处,接下来,我们就把目光放在go这个标签的位置,跟着CPU的步伐往后看:
go:
mov ax, cs
mov ds, ax
mov es, ax
mov ss ,ax
mov sp, #0xFF00
一眼望去,全是move操作。这段代码的意思很容易理解,就是把cs寄存器的值分别赋给ds,es和ss寄存器,然后再把0xFF00给了SP寄存器。
如果你能把Intel CPU手册月度一遍并且有个大概的认识,那理解这几行代码就不在话下了。
这些寄存器是干什么的
cs寄存器代表代码段寄存器,CPU即将要执行的代码在内存中的位置,就是由cs:ip这组寄存器配置指向的,其中cs是基址,ip是偏移地址。
之前执行过的一个段间跳转指令
jmpi go, 0x9000
这个指令的另一种伪代码表示为:
cs = 0x9000
ip = go
所以现在cs寄存器里的值就是0x9000,ip寄存器里的值就是go这个标签的偏移地址。所以刚刚说的三个mov指令就分别给ds,es和ss寄存器里的值赋为0x9000,也就是cs寄存器里的值。
ds为数据段寄存器,作为访问内存数据时的基地址。现在代码已经被挪到了0x90000处,所以现在自然又被赋值为0x9000了。
ss为栈段寄存器。后面要配合栈指针sp来表示此时的栈顶地址,而此时sp寄存器被赋值为0xFF00了,所以目前的栈顶地址就是ss:sp所指向的0x9FF