start: mov ax,#0x9000 ; this is done in bootsect already, but... mov ds,ax mov ah,#0x03 ; read cursor pos xor bh,bh int 0x10 ; save it in known place, con_init fetches mov [0],dx ; it from 0x90000.
int 0x10是触发 BIOS 提供的中断服务,具体来说是调用显示服务相关的中断处理程序,而 ah 寄存器被赋值为 0x03 表示显示服务里具体的读取光标位置功能这一个子服务。
这个 int 0x10 中断程序执行完毕并返回时,将会在 dx 寄存器里存储好光标的位置,具体说来其高八位 dh 存储了行号,低八位 dl 存储了列号。
比如获取内存信息。 ; Get memory size (extended mem, kB) mov ah,#0x88 int 0x15 mov [2],ax 获取显卡显示模式。 ; Get video-card data: mov ah,#0x0f int 0x10 mov [4],bx ; bh = display page mov [6],ax ; al = video mode, ah = window width 检查显示方式并取参数 ; check for EGA/VGA and some config parameters mov ah,#0x12 mov bl,#0x10 int 0x10 mov [8],ax mov [10],bx mov [12],cx 获取第一块硬盘的信息。 ; Get hd0 data mov ax,#0x0000 mov ds,ax lds si,[4*0x41] mov ax,#INITSEG mov es,ax mov di,#0x0080 mov cx,#0x10 rep movsb 获取第二块硬盘的信息。 ; Get hd1 data mov ax,#0x0000 mov ds,ax lds si,[4*0x46] mov ax,#INITSEG mov es,ax mov di,#0x0090 mov cx,#0x10 rep movsb
最终这些信息就存在了内存中固定的地方,可以当作全局变量:
调整内存布局
后续不再使用BIOS的中断,所以关闭中断。cli就是关闭中断
1
cli ; no interrupts allowed ;
继续向下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
; first we move the system to it's rightful place mov ax,#0x0000 cld ; 'direction'=0, movs moves forward do_move: mov es,ax ; destination segment add ax,#0x1000 cmp ax,#0x9000 jz end_move mov ds,ax ; source segment sub di,di sub si,si mov cx,#0x8000 rep movsw jmp do_move ; then we load the segment descriptors end_move: ...