Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1320790
  • 博文数量: 179
  • 博客积分: 4141
  • 博客等级: 中将
  • 技术积分: 2083
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-21 20:04
文章存档

2024年(1)

2019年(13)

2016年(1)

2014年(16)

2011年(8)

2010年(25)

2009年(115)

分类:

2009-03-21 22:10:01

1. permts 模块:

功能简介及其算法思路(算是猜测作者思路吧)

用于文本存储。由于labels存储的数据是变字长。所以采用ELF文件格式的名字存储(可以参看ELF文件格式,里面的很多算法对初学者还是蛮有用的,简单实用)。但是由于ELF格式的方法是在分析完之后的,可以一下子就获取总共需要的内存空间。这里所需要的文本空间是不可知的。所以作者采用了链表的形式,每个节点是可以存储PERMTS_SIZE个字节的数据,具体参看代码注释


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;
}

阅读(2282) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~