从HelloWold开始一个操作系统

来源:互联网 发布:淘宝网成交量 编辑:程序博客网 时间:2024/05/16 19:55

最近在阅读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处开始运行*/.code16start: 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 loop0DispStr:mov $msg   ,%axmov %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 $0x10ret.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:(直接拷贝于渊大哥的代码)

org07c00h; 告诉编译器程序加载到7c00处movax, csmovds, axmoves, axcallDispStr; 调用显示字符串例程jmp$; 无限循环DispStr:movax, BootMessagemovbp, ax; ES:BP = 串地址movcx, 16; CX = 串长度movax, 01301h; AH = 13,  AL = 01hmovbx, 000ch; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)movdl, 0int10h; 10h 号中断retBootMessage:db"Hello, OS world!"times 510-($-$$)db0; 填充剩下的空间,使生成的二进制代码恰好为512字节dw 0xaa55; 结束标志

编译方法:

nasm myboot.asm -o myboot

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


bochs运行效果如下: