从头写一个操作系统 03

写一个操作系统,需要学很多知识,但如果纯研究理论,一万个小时(常人的十年)也不可能面面俱到的完全掌握这些理论。
当然不是说这些理论有多复杂,恰恰是这些写进了书本的理论为了求大求全,把简单的知识讲的复杂了,让学的人不明所以,不知所图。比如龙书(编译原理)读起来艰深晦涩,但如果从程序运行的角度去看,编译器就是一个翻译软件,将文本翻译成可以执行的机器码或者中间代码,既然是翻译软件,那将'a b c' 翻译成'A B C'的软件就是最简单的编译器,真的有那么复杂吗?为什么要用那么多恐怖的理论,吓退满是求知欲的新人呢?
我推崇学任何知识都从最简单的实现开始,一步一步的深入,一点一点添枝加叶。如果每一本书都从这样的角度去讲解一门科学,无论是微积分,还是操作系统,并没有什么困难的地方,只不过是按部就班的耗费时间去思考去实践罢了。

linux系统的代码印成书,十几本也印不下,这样的操作系统是初学者没有办法学习的,只有在同样的路口有过同样的思考,你才会理解前人实现那样的文件系统,制定统一网络规范的原因。

这一次,我们需要理解一个叫"堆栈"(stack)的概念,堆栈用途很广,所以这种数据结构被起了这么个名字,其实这个东西想讲深了都讲不深,这就是一个长盒子装短盒子的结构,短盒子只能先进后出,后进先出,现实中的子弹夹就是堆栈,一颗一颗把子弹推入,又一颗一颗弹出来,总是最后进去的最先出来。

汇编中,用到堆栈的时候,一定会用到bp与sp两个寄存器,bp是堆栈的顶部,就是弹夹最靠外的位置,sp是弹簧,每压一颗子弹sp就向下压缩一格。

mov ah, 0x0e ; tty mode

mov bp, 0x8000 ; 将一个远离0x7c00的位置分配给堆栈,堆栈的顶为0x8000
mov sp, bp ;            初始化堆栈,sp指向堆栈顶部

push 'A'                 ;压入一个字节数据
push 'B'                  ;压入一个字节数据
push 'C'                   ;压入一个字节数据

mov al, [0x7ffe] ; 0x8000 - 2
int 0x10              ;不会不知道这个是什么意思吧?这是个中断,可以让屏幕显示al中的字节

; 不应该访问0x8000,这里没有数据,堆栈的第一个数据在0x8000-2处
mov al, [0x8000]
int 0x10


; 使用‘pop’来弹出堆栈中的数据
; 由于每次都会弹出两个字节数据,所以用两个字节的寄存器接收,而后取寄存器的低位
pop bx
mov al, bl
int 0x10 ; prints C

pop bx
mov al, bl
int 0x10 ; prints B

pop bx
mov al, bl
int 0x10 ; prints A

; data that has been pop'd from the stack is garbage now
mov al, [0x8000]
int 0x10


jmp $
times 510-($-$$) db 0
dw 0xaa55

要看懂上面的汇编代码很容易,亲自动手敲一遍,再编译运行起来,在学习的路上填一块砖。

你可能感兴趣的:(从头写一个操作系统 03)