启动补充说明
清理屏幕
上一节我们通过在显存地址直接写入字符,打印除了“hello”。但因为显存内存储着BIOS启动过程中的一些显示信息,所以屏幕看着很乱。这一节我们在打印字符之前,先讲显存内的内容清空,再进行打印,这样看着清爽些。
清空显存,当然有个笨办法,就是像打印“hello”一样,从0xb8000开始,向显存写入空白或不可见字符。但这个比较累。还有一个办法就是调用bios提供的int 10
中断。
int10中断
org 07c00h ; 告诉编译器程序加载到7c00处
;----中断10h,卷屏,实现清屏
mov ax, 0x0600
mov bx, 0x0700
mov cx, 0
mov dx, 0x184f
int 0x10
;----直接往显存中写数据
mov ax, 0xb800
mov gs, ax
mov byte [gs:0x00],'h'
mov byte [gs:0x02],'e'
mov byte [gs:0x04],'l'
mov byte [gs:0x06],'l'
mov byte [gs:0x08],'o'
times 510-($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw 0xaa55 ; 结束标志
以上代码中,我们先设置好参数,然后调用int 10
中断,实现了清屏操作。效果如下:
关于INT 10h的更多细节,可以看这里 wikipedia INT 10h。
内存布局
启动后,BIOS通过int 19
中断将第一个扇区对应的512字节拷贝至内存0x7c00处。那此时的内存布局是什么样子的呢?
如上图所示,点击电源键开机后,CPU处于实模式,即16位工作模式。但此时地址总线宽度为20位,最大寻址内存空间为2^20=1MB
。
实模式寻址
实模式下,CPU寻址方式为段基地址+段内偏移地址
,即每个内存单元可以用两个16位寄存器的值拼接而成。寄存器为16位,可以表示的最大段内偏移量为2^16=64KB
。CPU将16位段寄存器值左移4位得到段基地址,再加上段内偏移量,得到20位内存地址。