文件编译流程
GDT表
多任务结构
内存释放的3种情况
内核API
这些是应用程序可以调用的OS提供的函数,OS自身其实也会调用这些函数
void api_putchar(int c);
void api_putstr0(char *s);
void api_putstr1(char *s, int l);
void api_end(void);
int api_openwin(char *buf, int xsiz, int ysiz, int col_inv, char *title);
void api_putstrwin(int win, int x, int y, int col, int len, char *str);
void api_boxfilwin(int win, int x0, int y0, int x1, int y1, int col);
void api_initmalloc(void);
char *api_malloc(int size);
void api_free(char *addr, int size);
void api_point(int win, int x, int y, int col);
void api_refreshwin(int win, int x0, int y0, int x1, int y1);
void api_linewin(int win, int x0, int y0, int x1, int y1, int col);
void api_closewin(int win);
int api_getkey(int mode);
int api_alloctimer(void);
void api_inittimer(int timer, int data);
void api_settimer(int timer, int time);
void api_freetimer(int timer);
void api_beep(int tone);
回收内存的函数(解释都在注释里)
- 内存回收的原理:用一个数组记录空闲段的位置、大小,根据要回收的内存和空闲内存的位置关系,采取不同的方法,本质就是内存地址空间的合并
int memman_free(struct MEMMAN *man, unsigned int addr, unsigned int size)
/* 释放*/
{
int i, j;
/* 为便于归纳内存,将free[]按照addr的顺序排列 */
/* 即需要找到要释放的内存的前后空闲free的地址,因为后面肯定会合并的 */
for (i = 0; i < man->frees; i++) {
if (man->free[i].addr > addr) {
break;/* addr在这个区间:free[i - 1].addr < addr < free[i].addr */
}
}
if (i > 0) {
/* 前面有可用内存 */
if (man->free[i - 1].addr + man->free[i - 1].size == addr) {
/* 可以与前面的可用内存归纳到一起(也就是相邻的情况)*/
man->free[i - 1].size += size;
if (i < man->frees) {//这里感觉有点问题,i的初始值如果为0???
/* 后面也有 */
if (addr + size == man->free[i].addr) {
/* 也可以与后面的可用内存归纳到一起 */
man->free[i - 1].size += man->free[i].size;
/* man->free[i]删除*/
/* free[i]变成0后归纳到前面去 */
man->frees--;
for (; i < man->frees; i++) {
man->free[i] = man->free[i + 1]; /* 结构体赋值 */
}
}
}
return 0; /* 成功 */
}
}
/* 以下是i==0的情况 不能与前面的可用空间归纳到一起 */
if (i < man->frees) {
/* 后面还有 */
if (addr + size == man->free[i].addr) {
/* 但可以与后面的内容归纳到一起 */
man->free[i].addr = addr;
man->free[i].size += size;
return 0; /* 成功 */
}
}
/* 既不能与前面归纳到一起,也不能与后面归纳到一起 */
if (man->frees < MEMMAN_FREES) {// 如果还有free空间
/* free[i]之后的,向后移动,腾出一点可用空间 */
for (j = man->frees; j > i; j--) {
man->free[j] = man->free[j - 1];
}
man->frees++;
if (man->maxfrees < man->frees) {
man->maxfrees = man->frees; /* 更新最大值 */
}
man->free[i].addr = addr;
man->free[i].size = size;
return 0; /* 成功 */
}
/* 不能往后移动 ,没有free空间,空间管理信息用完*/
man->losts++;
man->lostsize += size;
return -1; /* 失敗 */
}
内存管理结构体
#define MEMMAN_FREES 4090 //允许4090个空闲段
#define MEMMAN_ADDR 0x003c0000
struct FREEINFO { /* 可用信息 */
unsigned int addr, size;
};
struct MEMMAN { /* 内存管理 */
int frees, maxfrees, lostsize, losts;
struct FREEINFO free[MEMMAN_FREES];/* 約32KB */
};