从HelloWold开始一个操作系统

最近在阅读linux早起内核的源码,可惜全是AT&T汇编,和以前学的大不一样,我们何不用AT&T汇编从一个HelloWorld开始实现一个小型操作系统,记得以前有本书叫<<一个操作系统的实现>>是用nasm汇编从一个HelloWorld开始实现了作者自己的操作系统。这其实是一个引导程序,因为PC机启动时ROM BIOS中的程序会把默认启动驱动器上的引导扇区代码和数据读入内存。好吧,那就从HelloWorld开始。

我们先来熟悉一下int10的13功能号,一会我们用的着

功能号:13H 
功能:在Teletype模式下显示字符串 
入口参数:AH=13H
          BH=页码
          BL=属性(若AL=00H或01H)
          CX=显示字符串长度
          (DH、DL)=坐标(行、列)
ES:BP=显示字符串的地址 AL= 显示输出方式 
0—字符串中只含显示字符,其显示属性在BL中。显示后,光标位置不变 
1—字符串中只含显示字符,其显示属性在BL中。显示后,光标位置改变 
2—字符串中含显示字符和显示属性。显示后,光标位置不变 
3—字符串中含显示字符和显示属性。显示后,光标位置改变


当AL=00H或01H时,BL中各位含义如下:
7      6  5  4      3      2  1  0

BL     R  G  B      I      R  G  B

闪烁    背景      高亮      前景

下面是AT&T汇编代码的myboot.s:

.text
.globl start/*程序从start处开始运行*/
.code16
start:
 jmpl $0x0, $code 
msg:
 .string "Hello world!"
code:
	mov     %cs,%ax   
	mov     %ax,%ds 
	mov     %ax,%es    
	mov     %ax,%ss  
	mov  $0x400,%sp  
	call DispStr/*调用显示字符串函数*/
			
loop0:/*无限循环*/
	jmp loop0
	
DispStr:
	mov $msg   ,%ax
	mov %ax    ,%bp/*es:bp = 串地址*/
	mov $12    ,%cx/*cs = 串长度*/
	mov $0x1301,%ax/*ah=13是功能号表示显示字符串 ,al=01是显示输出方式*/
	mov $0x000c,%bx/*bh=0是0页,bl=0ch高亮 黑底红字*/
	mov $0     ,%dl/*0行0列*/
	
	int $0x10
	ret
	
	
.org 0x1fe, 0x90 
.word 0xaa55 

编译方法:

as -o myboot.o -a myboot.s

ld --oformat binary -N -e start -Ttext 0x7c00 -o myboot myboot.o

dd bs=512 if=myboot of=Image count=1 conv=notrunc


下面是nasm汇编代码myboot.asm:(直接拷贝于渊大哥的代码)

	org	07c00h			; 告诉编译器程序加载到7c00处
	mov	ax, cs
	mov	ds, ax
	mov	es, ax
	call	DispStr			; 调用显示字符串例程
	jmp	$			; 无限循环
DispStr:
	mov	ax, BootMessage
	mov	bp, ax			; ES:BP = 串地址
	mov	cx, 16			; CX = 串长度
	mov	ax, 01301h		; AH = 13,  AL = 01h
	mov	bx, 000ch		; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)
	mov	dl, 0
	int	10h			; 10h 号中断
	ret
BootMessage:		db	"Hello, OS world!"
times 	510-($-$$)	db	0	; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw 	0xaa55				; 结束标志

编译方法:

nasm myboot.asm -o myboot

dd bs=512 if=myboot of=Image count=1 conv=notrunc


bochs运行效果如下:


你可能感兴趣的:(linux,linux,linux,汇编,操作系统)