自制操作系统(二) 一点小想法分享一下

    科技2022-07-11  108

    这节内容参考了《Orange…》的第四章(我觉的这里才是真正的开始) 那进入主题前,我先谈谈我的一个想法,目前我们只有一个boot.asm,但以后的asm文件就会多起来,可能有一些大家都想用的函数,但迫于语法,只能每个文件都写一遍,这就很麻烦,虽然在使用IDT之后会有很好的解决方法,不过在这之前,我想到了一种办法. 在汇编里,其实不存在什么函数,只不过是有机器指令的一个标号, 而这个标号,其实代表着一个内存地址,在汇编中,调用函数的指令是:

    call [函数] jmp [函数]

    那么按照上面的理论,[函数]这个其实是被编译成了这个函数的内存地址. 所以,假设putstr函数的内存地址为0xf000,那么

    jmp putstr == jmp 0xf000

    因此,我们可以把一个文件里定义的函数的内存地址保存到一个固定的地方(当然也是内存拉),别的文件要用的时候,只要jmp到这个地址就行了. 怎么实现呢? 首先创建一个新文件api.inc,它用来存放那个固定的地址.

    api_base equ 0xf000 api_putstr equ api_base + 0x0

    equ是equal的缩写,就是代替的意思,也就是写api_base和写0xf000是一样的. api_base是保存这些函数地址的地址头,后面的地址只要用它加上数字就可以了,不用去算,由于这种方法比较原始,所以我们规定内存地址的大小就定为16bit,占两位,所以每一个函数的地址= api_base + 0x02 * 序号.

    那么怎样把一个文件里定义的函数的内存地址保存到这个固定的地方,我们以putstr为例:

    boot.asm

    ... %include "api.inc" ;导入api.inc,其实就是把他拷进来 mov word[api_putstr],putstr ;mov,是move的意思,就是把右边的东西复制一份到左边去 ;api_putstr是要转送的地址,在mov中,在左边,[A]表示内存号为A的地址,在右边表示A这个地址里面的值,那么这句话就不难理解了. ;另外,mov要遵循一个原则,源地址位数等于目的地址位数,putstr的值明显大于0xff,所以[api_putstr]要用双字节,单字节是BYTE,双字节是WORD,四字节是DWORD,熟悉c语言的童鞋因该想起了c语言里的类型转换,和这个没什么区别的. ;函数声明 putstr: ;<-------标号 ... ;<-------一些语句 ret ;<-------返回,一定要有

    所以现在,外部文件要调用putstr只要导入api.inc,再

    jmp [api_putstr]

    就行了. 谈了这么多,其实并没有真的发挥作用,主要是因为软盘读取这边出了点问题,还在研究,问题也会在另一篇文章中发出来,有兴趣的童鞋可以去看一下.解决之后,立马就会更新下一篇,如果有时间的话,学业繁忙,多多见谅…

    Processed: 0.012, SQL: 8