30天自制操作系统

自制操作系统前5天内容的总结

- Hello World输出

; hello-os
; TAB=4

		ORG		0x7c00			; ORG命令指令程序开始地址
		JMP		entry			;无条件跳转到entry函数中
		//我寻思,后面这段代码不会执行啊,直接跳entry了
		//测试后发现如果不加后面这一段,是无法通过编译阶段的
		DB		0x90
		DB		"HELLOIPL"		;
		DW		512				; 
		DB		1				; 
		DW		1				; 
		DB		2				; 
		DW		224				; 
		DW		2880			;
		DB		0xf0			; 
		DW		9				; 
		DW		18				; 
		DW		2				;
		DD		0				; 
		DD		2880			; 
		DB		0,0,0x29		; 
		DD		0xffffffff		; 
		DB		"HELLO-OS   "	; 
		DB		"FAT12   "		; 
		RESB	18				; 

entry:
		MOV		AX,0			;0放入AX通用寄存器
		MOV		SS,AX			; 这里将栈顶位置设置成0,需要注意的是SS不能直										   	                                       ;接赋值
		MOV		SP,0x7c00       ;栈的偏移地址 SS:SP
		MOV		DS,AX           ;DS,ES均为段寄存器,一般在DS中存放即将访问的数;据地址
		MOV		ES,AX

		MOV		SI,msg          ;对源变址寄存器进行修改,作用为存放输出函数的地址
		//attention:能够只带地址的寄存器非常有限,只有BX,BP,SI,DI
putloop:
		MOV		AL,[SI]         ; 将SI的内存地址copy到AL
		ADD		SI,1			; SI++
		CMP		AL,0			; AL的值为0,即msg程序已经执行完成了
		JE		fin				;条件跳转
		MOV		AH,0x0e			; 
		MOV		BX,15			; 
		INT		0x10			; BIOS文档中调用显卡的中断
		/*
		显示一个字符:
		AH=0X0E;
		AL=character code;
		BH=0;
		BL=color code;
		*/
		JMP		putloop
fin:
		HLT						; 程序结束,CPU休眠
		JMP		fin				; 

msg:
		DB		0x0a, 0x0a		; 
		DB		"hello, world"  ;这里可以替换成各种字符,只要不超过内存上限
		DB		0x0a			; 
		DB		0

		RESB	0x7dfe-$		;在该地址后面填0,否则会报错
		DB		0x55, 0xaa
  • CPU部分寄存器的介绍

    • AX------accumulator
    • CX------counter
    • DX------data
    • BX------base
    • SP------stack pointer
    • BP------base pointer
    • SI ------source index
    • DI ------destination index

    以上给出的寄存器均为16位寄存器,其中AX,BX,CX,DX均可以拆分为高8位与低8位,反过来说,后面的四个寄存器是不能直接读取到其高8和低8位的。应该通过前4个16位寄存器来间接读取。

    mov AX SI
    再通过AH和AL来读取SI的高低8位。
    间接寻址 mov AL [SI] 将SI的内存地址赋值给AL,这种用法仅限于BX,BP,SI,DI

    到此,该系统还只是运行内存中的代码,而实际中操作系统需要从其他外部存储器获得程序运行所需要的的机器代码,所以后面增加了通过软盘为介质装载程序的步骤。
    增加的代码如下:

MOV		AX,0x0820
		MOV		ES,AX
		MOV		CH,0			; 柱面0
		MOV		DH,0			; 柱头0
		MOV		CL,2			; 扇区2

		MOV		AH,0x02			; AH=0x02 :读盘
		MOV		AL,1			; 1一个扇区
		MOV		BX,0
		MOV		DL,0x00			; A驱动器
		INT		0x13			; 调用磁盘BIOS
		JC		error			;JUMP if carray

中断号0x13手册中的说明为:

AH=0x02//读盘
AH=0X03;//写盘
AH=0x04;//校验
AH=0x0c;//寻道
AL=处理对象的扇区数;
CH=柱面号&0xff;
CL=扇面区(0-5位)|(柱面号&0x300)>>2;
DH=磁头号;
DL=驱动器号;
ES:BX=缓冲地址;
FLAGS.CF=0;没有错误
FLAGS.CF=1;有错误,错误号码存入AH内(与重置功能相同)

可以理解为该段代码设定了磁盘数据读入后存放的缓存区,ES:BX但是,磁盘存在读取过程中出现错误的可能性,所以将该段代码改为最多重复读取五次。

entry:
//配置上没有变化
		MOV		AX,0			 
		MOV		SS,AX
		MOV		SP,0x7c00
		MOV		DS,AX

		MOV		AX,0x0820
		MOV		ES,AX
		MOV		CH,0			 
		MOV		DH,0			
		MOV		CL,2			
		//将失败次数存到SI中
		MOV		SI,0			
retry:
		MOV		AH,0x02			
		MOV		AL,1			
		MOV		BX,0
		MOV		DL,0x00			
		INT		0x13			
		JNC		fin				
		ADD		SI,1			;SI++
		CMP		SI,5			; SI>=5?
		JAE		error			; SI >= 5  JMP error
		MOV		AH,0x00
		MOV		DL,0x00			; 使用驱动器A
		INT		0x13			; 触发中断
		JMP		retry

你可能感兴趣的:(操作系统)