⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 outieee.c

📁 32位汇编编译器nasm源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
                                break;
                            i -= EXT_BLKSIZ;
                        }
                        /* if we have an extern decide the type and make a record
                         */
                        if (eb) {
                            s.ftype = FT_EXTWRT;
                            s.addend = 0;
                            s.id2 = eb->index[i];
                        } else
                            error(ERR_NONFATAL,
                                  "Source of WRT must be an offset");
                    }

                } else
                    error(ERR_PANIC,
                          "unrecognised WRT value in ieee_write_fixup");
            } else
                error(ERR_NONFATAL, "target of WRT must be a section ");
        }
        s.size = size;
        ieee_install_fixup(segto, &s);
        return;
    }
    /* Pure segment fixup ? */
    if (segment != NO_SEG) {
        s.ftype = FT_SEG;
        s.id1 = 0;
        if (segment >= SEG_ABS) {
            /* absolute far segment fixup */
            s.id1 = -(segment - ~SEG_ABS);
        } else if (segment % 2) {
            /* fixup to named segment */
            /* look it up */
            for (target = seghead; target; target = target->next)
                if (target->index == segment - 1)
                    break;
            if (target)
                s.id1 = target->ieee_index;
            else {
                /*
                 * Now we assume the segment field is being used
                 * to hold an extern index
                 */
                long i = segment / 2;
                struct ExtBack *eb = ebhead;
                while (i > EXT_BLKSIZ) {
                    if (eb)
                        eb = eb->next;
                    else
                        break;
                    i -= EXT_BLKSIZ;
                }
                /* if we have an extern decide the type and make a record
                 */
                if (eb) {
                    if (realtype == OUT_REL2ADR || realtype == OUT_REL4ADR) {
                        error(ERR_PANIC,
                              "Segment of a rel not supported in ieee_write_fixup");
                    } else {
                        /* If we want the segment */
                        s.ftype = FT_EXTSEG;
                        s.addend = 0;
                        s.id1 = eb->index[i];
                    }

                } else
                    /* If we get here the seg value doesn't make sense */
                    error(ERR_PANIC,
                          "unrecognised segment value in ieee_write_fixup");
            }

        } else {
            /* Assume we are offsetting directly from a section
             * So look up the target segment
             */
            for (target = seghead; target; target = target->next)
                if (target->index == segment)
                    break;
            if (target) {
                if (realtype == OUT_REL2ADR || realtype == OUT_REL4ADR) {
                    /* PC rel to a known offset */
                    s.id1 = target->ieee_index;
                    s.ftype = FT_REL;
                    s.size = size;
                    s.addend = offset;
                } else {
                    /* We were offsetting from a seg */
                    s.id1 = target->ieee_index;
                    s.ftype = FT_OFS;
                    s.size = size;
                    s.addend = offset;
                }
            } else {
                /*
                 * Now we assume the segment field is being used
                 * to hold an extern index
                 */
                long i = segment / 2;
                struct ExtBack *eb = ebhead;
                while (i > EXT_BLKSIZ) {
                    if (eb)
                        eb = eb->next;
                    else
                        break;
                    i -= EXT_BLKSIZ;
                }
                /* if we have an extern decide the type and make a record
                 */
                if (eb) {
                    if (realtype == OUT_REL2ADR || realtype == OUT_REL4ADR) {
                        s.ftype = FT_EXTREL;
                        s.addend = 0;
                        s.id1 = eb->index[i];
                    } else {
                        /* else we want the external offset */
                        s.ftype = FT_EXT;
                        s.addend = 0;
                        s.id1 = eb->index[i];
                    }

                } else
                    /* If we get here the seg value doesn't make sense */
                    error(ERR_PANIC,
                          "unrecognised segment value in ieee_write_fixup");
            }
        }
        if (size != 2 && s.ftype == FT_SEG)
            error(ERR_NONFATAL, "IEEE format can only handle 2-byte"
                  " segment base references");
        s.size = size;
        ieee_install_fixup(segto, &s);
        return;
    }
    /* should never get here */
}
static void ieee_install_fixup(struct ieeeSection *seg,
                               struct ieeeFixupp *fix)
{
    struct ieeeFixupp *f;
    f = nasm_malloc(sizeof(struct ieeeFixupp));
    memcpy(f, fix, sizeof(struct ieeeFixupp));
    f->offset = seg->currentpos;
    seg->currentpos += fix->size;
    f->next = NULL;
    if (seg->fptr)
        seg->flptr = seg->flptr->next = f;
    else
        seg->fptr = seg->flptr = f;

}

/*
 * segment registry
 */
static long ieee_segment(char *name, int pass, int *bits)
{
    /*
     * We call the label manager here to define a name for the new
     * segment, and when our _own_ label-definition stub gets
     * called in return, it should register the new segment name
     * using the pointer it gets passed. That way we save memory,
     * by sponging off the label manager.
     */
    if (!name) {
        *bits = 16;
        if (!any_segs)
            return 0;
        return seghead->index;
    } else {
        struct ieeeSection *seg;
        int ieee_idx, attrs, rn_error;
        char *p;

        /*
         * Look for segment attributes.
         */
        attrs = 0;
        while (*name == '.')
            name++;             /* hack, but a documented one */
        p = name;
        while (*p && !isspace(*p))
            p++;
        if (*p) {
            *p++ = '\0';
            while (*p && isspace(*p))
                *p++ = '\0';
        }
        while (*p) {
            while (*p && !isspace(*p))
                p++;
            if (*p) {
                *p++ = '\0';
                while (*p && isspace(*p))
                    *p++ = '\0';
            }

            attrs++;
        }

        ieee_idx = 1;
        for (seg = seghead; seg; seg = seg->next) {
            ieee_idx++;
            if (!strcmp(seg->name, name)) {
                if (attrs > 0 && pass == 1)
                    error(ERR_WARNING, "segment attributes specified on"
                          " redeclaration of segment: ignoring");
                if (seg->use32)
                    *bits = 32;
                else
                    *bits = 16;
                return seg->index;
            }
        }

        *segtail = seg = nasm_malloc(sizeof(*seg));
        seg->next = NULL;
        segtail = &seg->next;
        seg->index = seg_alloc();
        seg->ieee_index = ieee_idx;
        any_segs = TRUE;
        seg->name = NULL;
        seg->currentpos = 0;
        seg->align = 1;         /* default */
        seg->use32 = *bits == 32;       /* default to user spec */
        seg->combine = CMB_PUBLIC;      /* default */
        seg->pubhead = NULL;
        seg->pubtail = &seg->pubhead;
        seg->data = NULL;
        seg->fptr = NULL;
        seg->lochead = NULL;
        seg->loctail = &seg->lochead;

        /*
         * Process the segment attributes.
         */
        p = name;
        while (attrs--) {
            p += strlen(p);
            while (!*p)
                p++;

            /*
             * `p' contains a segment attribute.
             */
            if (!nasm_stricmp(p, "private"))
                seg->combine = CMB_PRIVATE;
            else if (!nasm_stricmp(p, "public"))
                seg->combine = CMB_PUBLIC;
            else if (!nasm_stricmp(p, "common"))
                seg->combine = CMB_COMMON;
            else if (!nasm_stricmp(p, "use16"))
                seg->use32 = FALSE;
            else if (!nasm_stricmp(p, "use32"))
                seg->use32 = TRUE;
            else if (!nasm_strnicmp(p, "align=", 6)) {
                seg->align = readnum(p + 6, &rn_error);
                if (seg->align == 0)
                    seg->align = 1;
                if (rn_error) {
                    seg->align = 1;
                    error(ERR_NONFATAL, "segment alignment should be"
                          " numeric");
                }
                switch ((int)seg->align) {
                case 1:        /* BYTE */
                case 2:        /* WORD */
                case 4:        /* DWORD */
                case 16:       /* PARA */
                case 256:      /* PAGE */
                case 8:
                case 32:
                case 64:
                case 128:
                    break;
                default:
                    error(ERR_NONFATAL, "invalid alignment value %d",
                          seg->align);
                    seg->align = 1;
                    break;
                }
            } else if (!nasm_strnicmp(p, "absolute=", 9)) {
                seg->align = SEG_ABS + readnum(p + 9, &rn_error);
                if (rn_error)
                    error(ERR_NONFATAL, "argument to `absolute' segment"
                          " attribute should be numeric");
            }
        }

        ieee_seg_needs_update = seg;
        if (seg->align >= SEG_ABS)
            deflabel(name, NO_SEG, seg->align - SEG_ABS,
                     NULL, FALSE, FALSE, &of_ieee, error);
        else
            deflabel(name, seg->index + 1, 0L,
                     NULL, FALSE, FALSE, &of_ieee, error);
        ieee_seg_needs_update = NULL;

        if (seg->use32)
            *bits = 32;
        else
            *bits = 16;
        return seg->index;
    }
}

/*
 * directives supported
 */
static int ieee_directive(char *directive, char *value, int pass)
{

    (void)value;
    (void)pass;
    if (!strcmp(directive, "uppercase")) {
        ieee_uppercase = TRUE;
        return 1;
    }
    return 0;
}

/*
 * Return segment data
 */
static long ieee_segbase(long segment)
{
    struct ieeeSection *seg;

    /*
     * Find the segment in our list.
     */
    for (seg = seghead; seg; seg = seg->next)
        if (seg->index == segment - 1)
            break;

    if (!seg)
        return segment;         /* not one of ours - leave it alone */

    if (seg->align >= SEG_ABS)
        return seg->align;      /* absolute segment */

    return segment;             /* no special treatment */
}

/*
 * filename
 */
static void ieee_filename(char *inname, char *outname, efunc error)
{
    strcpy(ieee_infile, inname);
    standard_extension(inname, outname, ".o", error);
}

static void ieee_write_file(int debuginfo)
{
    struct tm *thetime;
    time_t reltime;
    struct FileName *fn;
    struct ieeeSection *seg;
    struct ieeePublic *pub, *loc;
    struct ieeeExternal *ext;
    struct ieeeObjData *data;
    struct ieeeFixupp *fix;
    struct Array *arr;
    static char boast[] = "The Netwide Assembler " NASM_VER;
    int i;

    /*
     * Write the module header
     */
    ieee_putascii("MBFNASM,%02X%s.\r\n", strlen(ieee_infile), ieee_infile);

    /*
     * Write the NASM boast comment.
     */
    ieee_putascii("CO0,%02X%s.\r\n", strlen(boast), boast);

    /* 
     * write processor-specific information
     */
    ieee_putascii("AD8,4,L.\r\n");

    /*
     * date and time
     */
    time(&reltime);
    thetime = localtime(&reltime);
    ieee_putascii("DT%04d%02d%02d%02d%02d%02d.\r\n",
                  1900 + thetime->tm_year, thetime->tm_mon + 1,
                  thetime->tm_mday, thetime->tm_hour, thetime->tm_min,
                  thetime->tm_sec);
    /* 
     * if debugging, dump file names
     */
    for (fn = fnhead; fn && debuginfo; fn = fn->next) {
        ieee_putascii("C0105,%02X%s.\r\n", strlen(fn->name), fn->name);
    }

    ieee_putascii("CO101,07ENDHEAD.\r\n");
    /*
     * the standard doesn't specify when to put checksums,
     * we'll just do it periodically.
     */
    ieee_putcs(FALSE);

    /* 
     * Write the section headers
     */
    seg = seghead;
    if (!debuginfo && !strcmp(seg->name, "??LINE"))
        seg = seg->next;
    while (seg) {
        char buf[256];
        char attrib;
        switch (seg->combine) {
        case CMB_PUBLIC:
        default:
            attrib = 'C';
            break;
        case CMB_PRIVATE:
            attrib = 'S';
            break;
        case CMB_COMMON:
            attrib = 'M';
            break;
        }
        ieee_unqualified_name(buf, seg->name);
        if (seg->align >= SEG_ABS) {
            ieee_putascii("ST%X,A,%02X%s.\r\n", seg->ieee_index,
                          strlen(buf), buf);
            ieee_putascii("ASL%X,%lX.\r\n", seg->ieee_index,
                          (seg->align - SEG_ABS) * 16);
        } else {
            ieee_putascii("ST%X,%c,%02X%s.\r\n", seg->ieee_index, attrib,
                          strlen(buf), buf);
            ieee_putascii("SA%X,%lX.\r\n", seg->ieee_index, seg->align);
            ieee_putascii("ASS%X,%X.\r\n", seg->ieee_index,
                          seg->currentpos);
        }
        seg = seg->next;
    }
    /*
     * write the start address if there is one
     */
    if (ieee_entry_seg) {
        for (seg = seghead; seg; seg = seg->next)
            if (seg->index == ieee_entry_seg)
                break;
        if (!seg)
            error(ERR_PANIC, "Start address records are incorrect");
        else
            ieee_putascii("ASG,R%X,%lX,+.\r\n", seg->ieee_index,
                          ieee_entry_ofs);
    }

    ieee_putcs(FALSE);
    /*
     * Write the publics
     */
    i = 1;
    for (seg = seghead; seg; seg = seg->next) {
        for (pub = seg->pubhead; pub; pub = pub->next) {
            char buf[256];
            ieee_unqualified_name(buf, pub->name);
            ieee_putascii("NI%X,%02X%s.\r\n", i, strlen(buf), buf);
            if (pub->segment == -1)
                ieee_putascii("ASI%X,R%X,%lX,+.\r\n", i, pub->index,
                              pub->offset);
            else
                ieee_putascii("ASI%X,%lX,%lX,+.\r\n", i, pub->segment * 16,
                              pub->offset);
            if (debuginfo) {
                if (pub->type >= 0x100)
                    ieee_putascii("ATI%X,T%X.\r\n", i, pub->type - 0x100);
                else
                    ieee_putascii("ATI%X,%X.\r\n", i, pub->type);
            }
            i++;
        }
    }
    pub = fpubhead;
    i = 1;
    while (pub) {
        char buf[256];
        ieee_unqualified_name(buf, pub->name);
        ieee_putascii("NI%X,%02X%s.\r\n", i, strlen(buf), buf);
        if (pub->segment == -1)
            ieee_putascii("ASI%X,R%X,%lX,+.\r\n", i, pub->index,
                          pub->offset);
        else
            ieee_putascii("ASI%X,%lX,%lX,+.\r\n", i, pub->segment * 16,
                          pub->offset);
        if (debuginfo) {
            if (pub->type >= 0x100)
                ieee_putascii("ATI%X,T%X.\r\n", i, pub->type - 0x100);
            else
                ieee_putascii("ATI%X,%X.\r\n", i, pub->type);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -