Linux源码学习笔记day5内存0地址处放的都是些什么玩意
上一次我们已经说到,操作系统的代码从硬盘复制到内存里了。
今天我们一起来看看,setup。s都做了啥?start:movcs,axmovax,dsmovax,esprintsomemessagemov0x03,ahxorbh,bhint0x10movdx,ds:0itfrom0x90000。
这里又发起了一个10号中断,上一次我们提到13号是BIOS提供的读磁盘中断程序。0x10号中断调用显示服务的中断处理程序。
把寄存器ah赋值成0x03是为了给显示服务里,读取光标位置的子服务。
0x10号中断程序结束时,会在dx寄存器里存储光标的位置:
高八位dh存储行号,
低八位dl存储列号。
注意:计算机加电自检后会自动初始化为文字模式,一屏25行,每行80列,一列一个字符。
接下来的mov指令就是把光标位置存储在这个内存地址给到ds:0的地址处。因为ds现在是0x9000,所以0x90000里存的就是光标的位置了。
感觉中断和我们平时调用函数有点类似,只不过用寄存器当作入参和返回值了。
接下来的一坨代码和上面逻辑差不多。调用中断程序获取点信息,存在内存里。Getmemorysize(extendedmem,kB)mov0x88,ahint0x15movax,ds:2Getvideocarddata:mov0x0f,ahint0x10movbx,ds:4bhdisplaypagemovax,ds:6alvideomode,ahwindowwidthcheckforEGAVGAandsomeconfigparametersmov0x12,ahmov0x10,blint0x10movax,ds:8movbx,ds:10movcx,ds:12Gethd0datamov0x0000,axmovax,dsldsds:40x41,simovINITSEG,axmovax,esmov0x0080,dimov0x10,cxrepmovsbGethd1datamov0x0000,axmovax,dsldsds:40x46,simovINITSEG,axmovax,esmov0x0090,dimov0x10,cxrepmovsb
经过上面的代码处理,现在内存地址里存储的数据大致如下图:
熟悉的rep指令
后面马上就要轮到C语言上场了,汇编语言和C语言之间的数据交互,虽然也可以用变量的形式进行传递。对于这种大量的数据,双方约定了一个内存地址(类似一个公用银行卡号),我存你取。
存储好数据之后,用cli关闭中断。
之所以关闭中断,是为了要写上我们自己的中断向量表,所以在这期间是不允许中断进来的。
接着看firstwemovethesystemtoitsrightfulplacemov0x0000,axclddirection0,movsmovesforwarddomove:movax,esdestinationsegmentadd0x1000,axcmp0x9000,axjzendmovemovax,dssourcesegmentsubdi,disubsi,simov0x8000,cxrepmovswjmpdomovethenweloadthesegmentdescriptors
最后repmovsw和之前从0x7c00复制到0x90000是一样的,只不过这一次是从0x10000到0x90000的内容都复制到0的位置。结果
现在内存布局大致是这个样子的:
可以看到从0到0x80000的这512K里是除了bootsect和setup的操作系统的代码。这么一来就把之前启动时的0x7c00那些内容都覆盖了。
0x7c00已经是前任了,感觉忘掉吧!
下一次,我们一起迎接新的篇章,模式转换
如果你觉得有点收获,欢迎点个关注,也欢迎分享给你身边的朋友。
头条创作挑战赛程序员