操作系统(哈工大)学习记录——课程P1-P3(上部分)

按照常例开始【胡言乱语】:迷迷糊糊的看完了前三课,静下心来一总结,今天学了些啥。发现脑子里基本啥也没有,就剩几个名词:BIOS、bootsect.s、setup、head.s、main,应用程序、os、硬件裸机……试着倒一下脑子,啥也没了......至于中间的汇编,啥玩意,把一个数据放在这个寄存器又放在另外一个寄存器,干嘛啊,麻了。寄存器?有多少个,每个是干嘛的,我都不知道。。。苦于还不会搭建个人博客,先把个人学习记录放在这里查询与备忘。

注:除了胡言乱语和标题部分,“【】”中括号均表示自己需要再次解决的地方,不明白的地方。

【目前的不足地方】

1.汇编语言的基础知识99%已经忘了,需要补充。想办法找个好理解的视频补补吧。

2.计算机组成原理需要补补要用的知识,这玩意目前没时间大补了,先找找片段知识用着。

汇编知识补充:内存的段划分及进制转换知识】

一、内存的分段

我们知道,计算机的数据是类似于纸带一样呈现带状的方式存储的,所以整个计算的数据可以看成一条丝带,宽度为一个数字的大小。所有数据全是0101穿成非常长的一条丝带,即使物理存储形式不是这样的,最后处理的方式也是呈现一条丝带。现在有一条非常长的数据带,如何让它实现抽象思维逻辑的具象化呢?就要类似于语言的表达,需要对应的标识符号表示对应的意思,所以为了尽可能表达更多的意思,就需要更多对应的逻辑方向,而如果只用一个1或0,就只能表达开或关的意思;而如果有两位数,就能表达00、01、10、11四个编号的意思,所以为了尽可能在有限的空间里表达更多的意思,那么就需要更多的位数表达更多的意思。那么需要的位数多了,存储的空间也需要多才能满足要求。

当存储的01非常多的时候,我们存放的逻辑意思就非常多了,这时候如果别人问你,我想找到之前存的A意思,噢,类似于房间东西非常多了,但你没有分类没有编号,你完全找不到东西在哪了,这时候,你存的再多的东西也等于没存了,因为你不能立马找出来,你只能一件一件的又全部翻出来找那个A意思,这太低效了。所以我们怎么都会想到给数据带分类或编号的工作,而做出8086的牛人们如何做的呢?他们把整个数据带“抽象”的剪成无数条“小带子”,然后再以小带子为基本单位进行编号,如果你想找到某个东西,那么你只需要首先找到是多少号小带子;然后再告诉我在小带子内是多少长度位置处,就可以快速找到那个东西了。

这里的“小带子”编号就是段地址,而小带子内多长就是偏移地址。还有就是,这些小带子都是逻辑上进行的划分,所以你可以以不同的位置切割,但有两个条件,一是切割地址必须是16的倍数,第二是每个小段必须小于64k(这是两个8位寄存器能索引的最大值了),所以可以出现我前一个是某个逻辑的带子划分,后一个就变化了,从而出现两个带子的地址范围出现重叠部分。【但是,内存是没有分段的哇,是cpu在使用内存时,我们主动对内存进行的编号。而且,分段的原因主要不是这个吧,好像是因为20位寻址线路,所以才需要基址+偏移实现20位吧?】 

汇编语言-段的概念_weixin_40788715的博客-CSDN博客_汇编语言段

汇编语言中 段的长度最大为为什么是64KB?,求详解_百度知道

汇编语言--段寄存器_盼盼编程的博客-CSDN博客_汇编语言段寄存器

二、进制的转换

一句话:相应位置的数量乘上相应位置的位权之后,所有进制最后一位(个位)的位权为1。

(不要再忘了,就记住句话浓缩就可以了)

如:

①80h 是十六位,从个位数到高位的位权分别是1,16,16x16;数量是8x16+0x1=128

②ffh,f是数量噢!是15,A是10,则15x16+15x1=256

③1111 1110,换为10进制是128+64+32+16+8+4+2+0=254也等于1 0000 0000-2=256-2=254

换为十六进制,四位换为一位十六进制,1111=f=8+4+2+1=15,1110=E=14

 【汇编知识补充:8086寄存器知识补充】来自:【汇编】SI DI 的用法 - 金舰 - 博客园

1.数据寄存器(通用寄存器),专门记录普通数据的。

有8个8位寄存器,两个一组,可以组成4组16位寄存器,分别有:

(ABCD,哈哈哈,顺序来的A加,B址,C数,D传)

AH + AL=AX 

(H表示高八位,L表示低八位)(0x表十六位,所以用也用x表两个合一起?)(还有汇编不在意大写,如ax,aX,AX是一个东西)

累加寄存器,【搞加法的?来源于ADD?】

BH + BL = BX  (base?)

基址寄存器,地址索引【地址搜索?】

CH + CL = CX

计算寄存器,计数用的,容易理解(count)

DH + DL = DX

数据寄存器,【emmm,又一个数据,这些不都叫数据寄存器吗】哦,后面说常用于数据传递,不如叫数据传递寄存器。

2.地址寄存器(段地址寄存器)

我们已经知道了为什么要切成小带子,也就是为什么要划分段,划分好了之后,为了不同用途带子进入专门的存储小盒子,给了三个不同的用途的寄存器作小盒子

CS:代码段寄存器(Code Segment)

不难理解,专门临时存写入代码的小带子(Segment是部分、片段的意思,寄存器是register)

DS:数据段寄存器(Data Segment)

存放写入数据的小带子

SS:堆栈段寄存器(Stack Segment)

【emmm,我只有对栈的一点理解,对堆一点想法都没有了,更不说他们的硬件存在方式了?】

ES:附加段寄存器(Extra Segment)

【这从英文上是额外的寄存器的意思哇,感觉像是一个备份的寄存器,差什么归不上类的,就用这个补上?】

3.特殊功能寄存器(指针寄存器)

IP:指令指针寄存器(Instruction Pointer)

【指令?指针?对指针还有一丢丢记忆,但这个指令,看英文意思吧,不看翻译意思】

【pointer,指针,指向的意思,类似小时候看书用手指指着某个字,然后阅读这个字】

【instruction,原意用法说明,说明书!衍生意指示、指令,合一起指示的指针、命令指针?】

说是与CS(code Segment,代码段寄存器)配合使用,可以追踪执行过程。

【啥意思,和代码段cs配合,如果ip是手指的话,那它存放的地址就可以直接指向正在执行的程序的代码位置哇?啥意思,要用ip指向一个临时的,已经从磁盘提取完内存片段的寄存器吗?这样有什么好处吗?换来了速度?但容量变小了哇,用快速读取来补充容量变小的问题吗?如同从一个大池子里取水放在一个小盆子里,小盆子又有一个小管子再取出里面的水,只要大管子速度够,怎么都不会出现小盆子用水枯竭?】

SP:堆栈指针(Stack Pointer)

【又是堆栈,更是指针,晕了】

说是与ss(stack segment,堆栈段寄存器)配合使用,可以指向目前堆栈位置

【啥意思哦,也是再次指向一个小盒子,然后中间有查表过程,再次指向大内存位置吗?】

BP:基址指针寄存器(Base Pointer)

【基址也给一个指针?这些玩意是干嘛的哇,指针指针指针。。。】

说是可以作为ss(stack segment,堆栈寄存器)的一个相对基址位置

【无法理解?】

4.特殊功能寄存器(变址寄存器)

SI:源变址寄存器(Source Index)

si可以用来存放相对于ds(data segment数据段寄存器)的源变址指针

【无法理解?】

DI:目的变址寄存器(Destination Index)

【目标变址寄存器,出发地源变址?然后目标变址?】

可用来存放相对于 ES (extra segment,额外寄存器)段之目的变址指针。 

【三个指针寄存器,两个变址寄存器】

【记录正文】

课程P1 What is Operating System?

1.回答标题:os是一个对计算机硬件进行管理的软件,是计算机硬件和应用之间的一层软件。

2.os管理哪些硬件?

cpu、内存、终端、磁盘、文件(单核cpu的os必须有的五个部分,本课程只讲那么多)

网络、电源、多核(开设于高级os课程,多cpu、并发实现等等)

3.学习os的不同层次

不同学校及学生有着对os不同的学习层次,李老师分为三类:

①从APP角度出发摸到os的边:

简言之,只集中于计算机“接口”的学习和了解,大脑里模模糊糊,是懂非懂、是否对是否不对的样子。

举个例子:使用显示器——printf,使用cpu——fork,使用文件系统——open,read等

 ②从APP角度出发进入了os:

 给你弄好了一些配套东西,让你编写或改写一个os(该课程最终目标)

如:能详细的描述一段文字是如何写到磁盘上的。

③从纯硬件出发设计并实现一个os:

如:给你一块板子,来给我设计一个好用的os。(也是我目前的最终目标,虽然很难,但我还是要给自己打气,你可以的!)

听老师说,该课程对标斯坦福的os,至于CMU的os就是第三层次的学习了,我也还看见了MIT的os,感觉很不错,但慢慢来,乱挖坑,绝对填不完,还容易到时候走不了路。弄清“原理”和“代码”,做好全部的实验,我的学习原因就是看着他有实验,不敲代码学习等于白学。

最后一句话课程P1总结:

Learning os concepts by coding them!

纸上得来终觉浅,绝知此事要躬行。

课程P2 Open the OS

哇,当时XP系统,熟悉的进度条,与长时间等待的开机黑屏画面。计算机在这个时候是在干什么呢?从通上电点亮电脑后,电脑是如何工作的呢?这其实已经让我疑惑了好多年。

一、计算机发展阶段的简单分类

1.从白纸到图灵机阶段:

1936年,英国数学家A.C.图灵(计算机科学之父)根据人脑计算方式,模拟人用笔在纸上算术提出了一个计算模型。这个模型有两个部分:纸带+控制器,纸带上写着数字=人在纸上写数字,控制器 =人脑,笔=计算完成后写在纸上的工具。

比如在纸带上写上1和2,再写上加号,控制器通过纸带先后读入1、2、加号,控制器便通过插表知道结果是3,并在纸带后面写上3。

【不足地方】这种模型只能处理一个问题,比如这个加法机只能算加法,不能解决其他问题,要是能通过纸带不同的标识,然后控制器看见标识换成对应的处理逻辑,就可以解决不同的问题了,这就引出了“通用图灵机”(不只是我的切换想法,通用图灵机还直接实现把处理方式写在纸上,就直接在问题的纸带上解决问题了,还不是我想的,还在在问题纸带前提前储备各种解决方式,虽然很相似,但是一个局限,一个灵活)

2.从“图灵机”到“通用图灵机”:

 老师把这个比作一个能看懂菜谱的厨师(能通过看不同菜谱就能做出不同菜的厨师),挺形象的。

抽象的解释这个模型,纸带上先写好控制器的动作,其实实质上就是一套处理逻辑,先提前输入一套控制器处理方式,之后再输入数据时,就会用相应的处理逻辑处理这个数据,然后输出结果。这个处理逻辑其实就是现在的APP。

【至于下一步升级的想法,目前不知道,后面填上、、】

3.从“通用图灵机”到“计算机”

这是下一个牛人的成果了——1946年冯·诺依曼提出的“存储程序思想”

主要思想:把程序啊数据啊全放在计算机的存储器里面,然后让软件程序控制计算机一步一步处理数据和程序。

这里的控制器就是一个指针(IP、PC)

IP指向存储器的第一句,mov ax,[100]    翻译:把操作数100放入目标寄存器ax里面。

【噢,我不知道了,这IR是啥玩意,咋就ax是0了】

二、计算机(x86 pc)启动的底层实现(汇编角度)

 打开电源

BIOS进入

①cpu默认为是实模式

(后面会讲对应的保护模式,实模式是老一代的Intel处理器的产物,内存小,性能低,该处理方式挺适合)(实模式的寻址方式是CS:IP,cs左移4位+ip,啥意思,在x86时候,处理器是16位的,所以两个寄存器也是,而cs左移四位+ip会有20位寻址宽度???【其实我也还没真正懂why?】)

②开机后,计算机自动设置cs=0xFFFF,ip=0x0000

cs是(代码)段寄存器,ip是段内偏移寄存器。保护模式下,cs和ip一起会产生一个地址,如何计算?cs<<4+ip,0xFFFF左移四位,这个左移是指的在计算本质语言(二进制)下左移四位。

【忘了一些,模拟计算一下】:

0xFFFF=1111 1111 1111 1111 ,也就是一个16进制的F用8421快速计算是4个二进制的1111,所以FFFF左移4位,是在16个1下左移四位,得到0xFFFF0,接着看第三步,全是设计得非常好的。

【至于左移是怎么实现的,目前先暂时不管,后面来填坑】

③寻址0xFFFF0

干嘛呢?cpu中一个代码都没有,怎么运行?所以先找到内存区中(ROM)的唯一有代码的地方——BIOS映射区,找吃的,这一步是主要是检查硬件有无问题。

④检查内存(RAM)、键盘、显示器、软硬磁盘、主板

这一步没问题,就要根据BIOS中的指令,开始读取磁盘中的代码了。

⑤把磁盘中0磁道0扇区的内容读出来放到内存中的0x7c00处

 一个扇区512byte,而0磁道0扇区就是os的“引导扇区”。这个扇区存放的是os的第一段代码。

【备注一下】磁盘(机械硬盘):

平常见到的一个有点大的方盒子,类似U盘功能的玩意,主要是连接电脑,这个盒子会动,明显感觉里面有个东西在转动。这么久了,才知道,磁盘其实就之前cd的存储方式,不过磁盘有很多张“CD”叠在一起,而且双面都可以存储数据。严格的术语,“CD”叫盘片,每个盘片有两个盘面,对应的每个盘面都有一个磁头,所有磁头都连接在一个轴上,所有所有磁头有共进退的特性。

 视角缩小到一张盘面上,如果按照一个同心圆就是一个磁道,类似于圆形跑道划分方式,那么整个盘面可以分为0号磁道、1号磁道......

如果按照类似切蛋糕的方式划分盘面,又可以把盘面划分为0号扇区、1号扇区......

所以os的“引导扇区”就是一块类似西瓜皮的侧面样子。

⑥设置cs=0x07c0 ,ip=0x0000

计算一下cs:ip是多少,cs左移4位,0x7c00+0=0x7c00,刚好就是刚才把os引导扇区取出来放的地址7c00,ok,现在bios退出舞台,计算机开始进行我们写的os引导扇区代码了。

os引导扇区进入(进入我们写入的512字节的故事,给你,你会怎么写呢?)

这里面别人写了一个串代码,叫bootsect.s,这里的.s文件就是汇编代码的意思。后面会再次提到,汇编语言不只只有一种汇编语言,随着计算机发展还出现了其他两种。

为什么不用c语言?

因为c语言最终还是会经过汇编这层语言,最后才转成机器码,但主要的是c编译后,你不清楚数据具体流向,是在哪个寄存器了等等不能完全控制数据流向的问题,而汇编不会,应用汇编语言,你可以完全控制数据的流向,这也意味着所有的事都需要你自己一手完成(ps.我挺喜欢的),但随之而来的是难度的增大。下面的bootsect.s最终通过编译后,形成机器码放在引导扇区上。

一、bootsect.s

.globl begtext,begdata,begbss,endtext,enddata,endbss
.text //文本段
begtext:
.data //数据段
begdata:
.bss //未初始化数据段
begbss:
entry start //关键字entry告诉链接器“程序入口”
start:
mov ax, #BOOTSEG mov ds, ax
mov ax, #INITSEG mov es, ax
mov cx, #256 
sub si, si sub di,di
rep movw 
jmpi go, INITSEG

 1.开头——start

【emmm,感觉那本linux源码分析书还是得买哇,看不懂写的些啥】

【这第一行,一堆点什么的干什么的啊,大致猜测点global begtext是全局..开始/启动文本,然后是启动数据,启动未初始化数据,结束文本,结束数据,结束未初始化数据,什么鬼】

【之后三个注释,说什么点text是假的操纵符,还有什么重叠,不分段是什么意思?】

entry 告之“链接器”程序入口,链接器???《编译原理》?没学过啊。emmm在这里告知,那前面的就不编译了,不要了?

2.start——结束

第①行:mov ax, #BOOTSEG mov ds, ax

(16位汇编),源操作数(啥玩意名字,就是拿出东西的那个)在右边,目标操作数在左边。所以

把#BOOTSEG(源操作数)的东西给ax——>   0x07c0 给 ax

【这个#是干嘛,不理解,什么玩意立即寻址,能不能说形象一些】

下一个mov,是把ax给ds,把刚给ax的东西又给ds——> ds=0x07c0

第②行:mov ax, #INITSEG mov es, ax

同理,传两次数据,完成后es=0x9000

从汇编知识上看出,ds和es都是段寄存器,是不能形成地址的,还要加上段内偏移,刚好,下面就是实现段内偏移的。

第③行:mov cx, #256

cx=256

第④行:sub si, si sub di,di

实现段内偏移。【查了一下,sub是汇编中减法的意思,还是什么“不借位减法”,我连减法都没弄明白怎么实现,就别来多了】

sub si,si    【自己减自己,嗯我知道,但换一个呢,①又是谁减谁呢?②减完之后结果怎么办呢,不处理结果,你减它干嘛,噢!原来这个sub是源操作数放下面,用目标操作数减它,然后把结果存在目标操作数里,哎 !类似于c语言的a=a-b,如sub ax,ds等同于ax=ax-dx。】

【疑问③这个si是啥,不会是什么玩意的低八位或高八位吧?后面补了一下汇编,知道不是。

——疑问解决2022.4.26,si是index,source index,源变址寄存器】

ok,两个自减存了两个给自己。

ds:si配合使用(data segment数据段,和source index源地址),作源地址,ds:si=0x07c0:0x0000,逻辑地址变物理地址,左移4位+偏移

es:di配合是使用,(extra segment额外段,和destination index目标地址)作目标地址,

es:di=0x9000:0x0000

第⑤行:rep movw

rep是循环执行的意思,循环的次数由计数寄存器cx决定。上一句给了cx 256次循环次数,那么要执行256次,直到cx=0

movw复制一个字

rep movw 反复将源地址的代码一个字一个字的复制到目标地址处,复制cx次,就等于复制256个字过去【是不是每次复制都会将ip还是啥的标志位+1呢?不然怎么实现一个接一个的复制呢?不然就只反复复制第一个了】,从7c00处的后续256个字的代码,复制到9 0000处之后的位置。

补充

  • movl 
    mov long : 字长传送 : 32位
  • movw 
    mov word:字传送 :16位
    (word,对字为单位进行传送,mov后加补充说明l、w、b)
  • movb 
    mov byte:字节传送 :8位

【这个movw哇,这种复制移动,是一开始就已经设置好从某个寄存器开始,然后到某个目标寄存器了,如何实现的哇?有个什么逻辑电路?还是有个逻辑代码?还是固化在其中的cpu进程代码?目前不知】

做此个移动的目的,是为后续某个工作腾出看空间,这很好理解。

第⑥行:jmpi go, INITSEG

【补一个更厉害的讲解:你管这破玩意叫操作系统源码 | 第二回 自己给自己挪个地儿-技术圈

jmp段间跳转指令,后面的go,INTSEG等价于INITSEG:go的形式,基地址+偏移地址。

也就是把go给ip,把INTSEG给cs。这个go其实就是一个标签(标号),最后汇编成成机器码后,go这条指令需要偏移多少地址就是多少地址。最后执行后,就会跳转到go的内容地方。

总结:

所以现在干的事,就是把一段 512 字节的代码,从硬盘的启动区先被移动到了内存 0x7c00 处,然后又立刻被移动到 0x90000 处,并并且加上go的偏移标签地址,也就是 mov ax,cs 这行指令的位置。

下一部分:jmpi go, INITSEG内容

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值