struct permts { /* permanent text storage */ struct permts *next; /* for the linked list */ int size, usage; /* size and used space in ... */ char data[PERMTS_SIZE]; /* ... the data block itself */ };
static struct permts *perm_head; /* start of perm. text storage */ static struct permts *perm_tail; /* end of perm. text storage */
static char *perm_copy(char *string1, char *string2) { char *p, *q;
int len = strlen(string1) + strlen(string2) + 1;
if (perm_tail->size - perm_tail->usage < len) { /* 如果缓存不够,在重新申请一个 */ perm_tail->next = (struct permts *)nasm_malloc(sizeof(struct permts)); perm_tail = perm_tail->next; perm_tail->next = NULL; perm_tail->size = PERMTS_SIZE; perm_tail->usage = 0; } /* copy 数据 */ p = q = perm_tail->data + perm_tail->usage; while ((*q = *string1++)) q++;
while ((*q++ = *string2++)) ;
perm_tail->usage = q - perm_tail->data;
return p; }
1. 实际的标签处理 算法思路: 使用开散列
代码注释:
union label { /* actual label structures */ struct { long segment, offset; char *label, *special; int is_global, is_norm; } defn;
struct { long movingon, dummy; union label *next; } admin; };
int init_labels(void) { int i;
for (i = 0; i < LABEL_HASHES; i++) { ltab[i] = (union label *)nasm_malloc(LBLK_SIZE); if (!ltab[i]) return -1; /* can't initialise, panic */ init_block(ltab[i]); lfree[i] = ltab[i]; } perm_head = perm_tail = (struct permts *)nasm_malloc(sizeof(struct permts));
if (!perm_head) return -1;
perm_head->next = NULL; perm_head->size = PERMTS_SIZE; perm_head->usage = 0; prevlabel = "";
initialised = TRUE;
return 0; } /* * Internal routine: finds the `union label' corresponding to the * given label name. Creates a new one, if it isn't found, and if * `create' is TRUE. */ /* * create: 0:仅仅是查找label 1:如果查找不到,就将该lable插入 */ static union label *find_label(char *label, int create) { int hash = 0; char *p, *prev; int prevlen; union label *lptr; if (islocal(label)) prev = prevlabel; else prev = ""; prevlen = strlen(prev); p = prev;
/* 哈希函数的计算 */
while (*p) hash += *p++; p = label; while (*p) hash += *p++; hash %= LABEL_HASHES; lptr = ltab[hash]; while (lptr->admin.movingon != END_LIST) { if (lptr->admin.movingon == END_BLOCK) { lptr = lptr->admin.next; if (!lptr) break; } if (!strncmp(lptr->defn.label, prev, prevlen) && !strcmp(lptr->defn.label + prevlen, label)) return lptr; lptr++; }
if (create) { if (lfree[hash]->admin.movingon == END_BLOCK) { /* 如果 lfree 的内存已经用光了,申请一块大小为 LBLK_SIZE 的内存,然后初始化给内存块 */ /* * must allocate a new block */ lfree[hash]->admin.next = (union label *)nasm_malloc(LBLK_SIZE); lfree[hash] = lfree[hash]->admin.next; init_block(lfree[hash]); } lfree[hash]->admin.movingon = BOGUS_VALUE; lfree[hash]->defn.label = perm_copy(prev, label); lfree[hash]->defn.special = NULL; lfree[hash]->defn.is_global = NOT_DEFINED_YET; return lfree[hash]++; } else return NULL; } int lookup_label(char *label, long *segment, long *offset) { union label *lptr; if (!initialised) return 0; lptr = find_label(label, 0); if (lptr && (lptr->defn.is_global & DEFINED_BIT)) { *segment = lptr->defn.segment; *offset = lptr->defn.offset; return 1; } else return 0; }
|