编写malloc
昨天的带窗口的应用程序,窗口的buffer是全局数组,导致生成的可执行文件很大。如果可以在运行时动态分配就可以解决这个问题。但是直接使用操作系统的memman_alloc()也不行,因为分配到的内存空间不属于应用程序的段。临时的解决方法是在编译时就把数据段开大一点,然后再用memman管理这段内存。因为分配的数据段大小不会对可执行文件的大小产生影响,所以是可行的。
malloc用的内存空间的起始地址在.hrb文件的0x0020处。0x0000是应用程序数据段的大小,包括栈,原有的数据和malloc用的内存空间。在winhelo.hrb中的情况是:
0x0000 B000 ;数据段大小
0x000c 0400 ;栈初始地址
0x0010 0013
0x0020 0420 ;malloc用的内存空间
然后分别编写_api_initmalloc,_api_malloc,_api_free三个汇编函数,用于初始化,分配和释放内存。
在_api_initmalloc中,
_api_initmalloc: ; void api_initmalloc(void);
PUSH EBX
MOV EDX,8
MOV EBX,[CS:0x0020]
MOV EAX,EBX
ADD EAX,32*1024
MOV ECX,[CS:0x0000]
MOV ESI,ECX
SUB ECX,EAX
INT 0x40
POP EBX
RET
可以看到真正的可分配的内存大小ECX只有0x2BE0这么大。前面的32KB是放内存管理表的。因为MEMMAN结构是和操作系统用的一样,然而操作系统可管理的内存大得多,所以这里损失比较大。
键盘输入API
前面的绘图API比较简单没什么可讲的。这里的键盘输入API提供了阻塞和非阻塞两种方式。在hrb_api()中,用了一个for循环,如果是非阻塞,检测FIFO并立即返回字符或-1。如果是阻塞,则当FIFO空时睡眠。
在应用程序中也有两种调用API的方式。如:
for(;;){
if(api_getkey(1)==0x0a){
break;
}
}
传的参数是1,是阻塞的。