首页
登录 | 注册

Nasm源代码解析 预处理器--总结(八)

1.  内存块操作

数据结构和算法:

数据结构是链表

当插入一个block的时候,将该块插入到链表的结尾(思考:是否可以考虑插入到链表头呢?这样貌似对程序没有影响啊,而且大大提高了效率。)

注意:删除block链表:由于头指针的静态变量,不能删除

/*
* Tokens are allocated in blocks to improve speed
*/

struct Blocks
{
Blocks *next;
void *chunk;
};

static Blocks blocks = { NULL, NULL };
static void *new_Block(size_t size);
static void delete_Blocks(void);

/*
* this function allocates a new managed block of memory and
* returns a pointer to the block. The managed blocks are
* deleted only all at once by the delete_Blocks function.
*/
static void *new_Block(size_t size)
{
Blocks *b = &blocks;

/* first, get to the end of the linked list */
/* 个人观点:可以建立一个指向链表结尾的指针,这样就无需循环获取放在链表尾部的指针了,可以* 大大提高效率 */
while (b->next)
b = b->next;

/* now allocate the requested chunk */
b->chunk = nasm_malloc(size);

/* now allocate a new block for the next request */
b->next = nasm_malloc(sizeof(Blocks));

/* and initialize the contents of the new block */
b->next->next = NULL;
b->next->chunk = NULL;
return b->chunk;
}

/*
* this function deletes all managed blocks of memory
*/
static void delete_Blocks(void)
{
Blocks *a, *b = &blocks;

/*
* keep in mind that the first block, pointed to by blocks
* is a static and not dynamically allocated, so we don't
* free it.
*/
while (b) {
if (b->chunk)
nasm_free(b->chunk);
a = b;
b = b->next;
if (a != &blocks)
nasm_free(a);
}
}

2.  Token存储功能操作

Token功能是以以上的块操作为基础开发出来的:

数据结构:链表

#define TOKEN_BLOCKSIZE 4096
static Token *freeTokens = NULL; /* 空闲的token链表头 */
struct Token
{
Token *next;
char *text;
SMacro *mac; /* associated macro for TOK_SMAC_END */
int type;
};

enum {
TOK_WHITESPACE = 1, TOK_COMMENT, TOK_ID, TOK_PREPROC_ID, TOK_STRING,
TOK_NUMBER, TOK_SMAC_END, TOK_OTHER, TOK_SMAC_PARAM,
TOK_INTERNAL_STRING
};

/*
* this function creates a new Token and passes a pointer to it
* back to the caller. It sets the type and text elements, and
* also the mac and next elements to NULL.
*/
static Token *new_Token(Token * next, int type, char *text, int txtlen)
{
Token *t;
int i;

/* 先获取一个大块,然后在这个大块内存中建立一个链表,freeTokens指向空闲链表的头指针 */
if (freeTokens == NULL) {
freeTokens = (Token *) new_Block(TOKEN_BLOCKSIZE * sizeof(Token));
for (i = 0; i < TOKEN_BLOCKSIZE - 1; i++)
freeTokens[i].next = &freeTokens[i + 1];
freeTokens[i].next = NULL;
}

/* 取出一个空闲块 */
t = freeTokens;
freeTokens = t->next;

/* 初始化 t */
t->next = next;
t->mac = NULL;
t->type = type;

/* 存放token */
if (type == TOK_WHITESPACE || text == NULL) {
t->text = NULL;
} else {
if (txtlen == 0)
txtlen = strlen(text);
t->text = nasm_malloc(1 + txtlen);
strncpy(t->text, text, txtlen);
t->text[txtlen] = '\0';
}
return t;
}

/* 将空闲的内存块插入freeTokens中 */
static Token *delete_Token(Token * t)
{
Token *next = t->next;
nasm_free(t->text);
t->next = freeTokens;
freeTokens = t;
return next;
}

3.static Token *tokenise(char *line)函数中,有一个函数链表操作(其实在Nasm中,经常采用这种方式创建链表的方式),这个链表操作值得我们学习,现在我将相关代码抽出来:

Token *list = NULL;
Token *t, **tail = &list; /* list是链表头,tail总是指向链表尾 */
*tail = t = new_Token(NULL, type, line, p - line); /* 将 t 插入到 list 链表中 */
tail = &t->next;


相关文章

  • 注意,我并不会是百分之一百正确的.例如,一个系统很可能没有/proc文件系统支持,但是大多数系统肯定有.这里我假定你是"随大流的",并有一个典型配置的系统. 什么是符号(Symbols)? 内核符号表(Kernel Sy ...
  • 使用Eclipse AST生成java源代码(一)
    一.AST版"Hello World" Java代码 public class HelloWorld { public static void main(String[] args) { AST ast = AST.ne ...
  • Redis源码解析--NET
        关于Redis资料:     要看原滋原味的请点这里,要看有我参与的山寨货请点这里,当然我也不反对看这里.     在接下来的日子里,我会记录下我对Redis源码的一些认识,首先从Event driven programming l ...
  • 作者:gfree.wind@gmail.com 博客:linuxfocus.blog.chinaunix.net 微博:weibo.com/glinuxer QQ技术群:4367710 github:https://github.com/g ...
  • 齿数是8,64是由减速比1:64得到的,内部转子的步距角是5.625,即360/(8*8),第一个8是指转子齿数,第二个8是指8拍. 64个脉冲电机转一圈,如果你用程序写64个脉冲进去你会发现输出轴看似没动过,然后你就设置64*64个脉冲, ...
  • List Comprehensions 和 Generator Expressions解析 By Harrison Feng List Comprehensions和Generator Expressions是Python里十分常用的在复杂 ...

2020 unjeep.com webmaster#unjeep.com
12 q. 0.013 s.
苏ICP备12049786号-20