c/c++研究和学习

lcc源码学习(3)

从main函数学起:

使用的数据结构:

1 typedef struct list *List;
2 struct list {        /* 循环链表 */
3     char *str;        /* option 或者文件名 */
4     List link;        /* next list element */
5 };
6 
7 static List llist[2];        /* loader files, flags */
8 static List alist;           /* assembler flags */
9 static List clist;           /* compiler flags */
10 static List plist;         /* preprocessor flags */
11 static List ilist;          /* 环境变量LCCINPUTS定义的includes目录 */
12 static List rmlist;       /* list of files to remove */
13 
14 
15 static List lccinputs;        /* list of input directories */

main函数的调用关系:main2.jpg

 win32.c只是为了处理windows和linux之间可移植性做的一个替换。

其中重要的数据和数据结构 :

#define LCCDIR "\\progra~1\\lcc\\4.1\\bin\\"
char *suffixes[] = { ".c;.C", ".i;.I", ".asm;.ASM;.s;.S", ".obj;.OBJ", ".exe", 0 };
char *cpp[] = { LCCDIR "cpp", "-D__STDC__=1", "-Dwin32", "-D_WIN32", "-D_M_IX86","$1", "$2", "$3", 0 };
char *include[] = { "-I" LCCDIR "include", 0 };
char *com[] = { LCCDIR "rcc", "-target=x86/win32", "$1", "$2", "$3", 0 };
char *as[] = { "ml", "-nologo", "-c", "-Cp", "-coff", "-Fo$3", "$1", "$2", 0 };
char *ld[] = { "link", "-nologo", "", "-subsystem:console", "-entry:mainCRTStartup","$2", "-OUT:$3", "$1", LCCDIR "liblcc.lib", "oldnames.lib", "libc.lib", "kernel32.lib", 0 };

win32.c里只有一个函数int option(char *arg),用来处理路径名。也就是根据环境设置变量设置(lcc安装位置),将程序调用的查找位置设置好(LCCDIR)。

现在来看main.c中各个函数功能。

alloc:

1 static void *alloc(int n) {
2     static char *avail, *limit;
3    
4     n = (n + sizeof(char *) - 1)&~(sizeof(char *) - 1);
5     if (n >= limit - avail) {
6         avail = malloc(n + 4*1024);
7         assert(avail);
8         limit = avail + n + 4*1024;
9     }
10     avail += n;
11     return avail - n;
12 }

这是个分配空间的函数。其中有几点需要注意。

1、第4行,实际分配的是一个大于等于传进来参数的空间。而且是一个对齐char*大小的空间。32位机器上,char*是4字节的。空间按照4字节对齐。

2、空间管理也很有趣,不是每次分配向系统申请空间,而是先检查现行空间是不是够分配,够分配,就直接在现行空间中分配,通过第10行,移动avail指针完成。不够分配向系统重新申请空间。每次向系统申请时,多申请4K空间。申请后avail指向新申请空间,用limit指向空间的最后作为界限。

3、这样管理空间,一方面,对于经常需要动态申请小量空间情况,提高了空间分配效率,减少了系统空间碎片。但另一方面,对于申请来的每一块空间末尾,会频繁出现浪费。极端情况是每当需要申请大于4K空间时,都需要重新向系统申请。原来申请的那块空间未使用部分就浪费了。

append:

1 static List append(char *str, List list) {
2     List p = alloc(sizeof *p);
3 
4     p->str = str;
5     if (list) {
6         p->link = list->link;
7         list->link = p;
8     } else
9         p->link = p;
10     return p;
11 }

这个是个简单的链表添加节点函数。生成包含参数str内容的节点,参数list指定链表为空,节点的link指向自身,否则,节点插入到list里。返回List p。

这个函数是要被反复使用的函数,main.c中使用的数据结构里,多个链表都是用这个函数建立起来的。

posted on 2008-10-28 14:26 昆仑大鹏 阅读(960) 评论(0)  编辑 收藏 引用 所属分类: lcc 源码学习


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理