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

📄 assemble.c

📁 nasm的全套源代码,有些我做了些修改,以方便您更方便更容易调试成功,方便学习做编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
                data = ins->oprs[c - 064].offset - insn_end;
                out(offset, segment, &data,
                    OUT_ADDRESS + size, NO_SEG, NO_SEG);
            }
            offset += size;
            break;

        case 070:
        case 071:
        case 072:
            if (ins->oprs[c - 070].segment != segment) {
                data = ins->oprs[c - 070].offset;
                out(offset, segment, &data,
                    OUT_REL4ADR + insn_end - offset,
                    ins->oprs[c - 070].segment, ins->oprs[c - 070].wrt);
            } else {
                data = ins->oprs[c - 070].offset - insn_end;
                out(offset, segment, &data,
                    OUT_ADDRESS + 4, NO_SEG, NO_SEG);
            }
            offset += 4;
            break;

        case 0130:
        case 0131:
        case 0132:
            data = ins->oprs[c - 0130].offset;
            if (is_sbyte(ins, c - 0130, 16)) {
                bytes[0] = data;
                out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
                    NO_SEG);
                offset++;
            } else {
                if (ins->oprs[c - 0130].segment == NO_SEG &&
                    ins->oprs[c - 0130].wrt == NO_SEG &&
                    (data < -65536L || data > 65535L)) {
                    errfunc(ERR_WARNING, "word value exceeds bounds");
                }
                out(offset, segment, &data, OUT_ADDRESS + 2,
                    ins->oprs[c - 0130].segment, ins->oprs[c - 0130].wrt);
                offset += 2;
            }
            break;

        case 0133:
        case 0134:
        case 0135:
            codes++;
            bytes[0] = *codes++;
            if (is_sbyte(ins, c - 0133, 16))
                bytes[0] |= 2;  /* s-bit */
            out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
            offset++;
            break;

        case 0140:
        case 0141:
        case 0142:
            data = ins->oprs[c - 0140].offset;
            if (is_sbyte(ins, c - 0140, 32)) {
                bytes[0] = data;
                out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
                    NO_SEG);
                offset++;
            } else {
                out(offset, segment, &data, OUT_ADDRESS + 4,
                    ins->oprs[c - 0140].segment, ins->oprs[c - 0140].wrt);
                offset += 4;
            }
            break;

        case 0143:
        case 0144:
        case 0145:
            codes++;
            bytes[0] = *codes++;
            if (is_sbyte(ins, c - 0143, 32))
                bytes[0] |= 2;  /* s-bit */
            out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
            offset++;
            break;

        case 0300:
        case 0301:
        case 0302:
            if (chsize(&ins->oprs[c - 0300], bits)) {
                *bytes = 0x67;
                out(offset, segment, bytes,
                    OUT_RAWDATA + 1, NO_SEG, NO_SEG);
                offset += 1;
            } else
                offset += 0;
            break;

        case 0310:
            if (bits == 32) {
                *bytes = 0x67;
                out(offset, segment, bytes,
                    OUT_RAWDATA + 1, NO_SEG, NO_SEG);
                offset += 1;
            } else
                offset += 0;
            break;

        case 0311:
            if (bits == 16) {
                *bytes = 0x67;
                out(offset, segment, bytes,
                    OUT_RAWDATA + 1, NO_SEG, NO_SEG);
                offset += 1;
            } else
                offset += 0;
            break;

        case 0312:
            break;

        case 0320:
            if (bits == 32) {
                *bytes = 0x66;
                out(offset, segment, bytes,
                    OUT_RAWDATA + 1, NO_SEG, NO_SEG);
                offset += 1;
            } else
                offset += 0;
            break;

        case 0321:
            if (bits == 16) {
                *bytes = 0x66;
                out(offset, segment, bytes,
                    OUT_RAWDATA + 1, NO_SEG, NO_SEG);
                offset += 1;
            } else
                offset += 0;
            break;

        case 0322:
            break;

        case 0330:
            *bytes = *codes++ ^ condval[ins->condition];
            out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
            offset += 1;
            break;

        case 0331:
        case 0332:
            break;

        case 0333:
            *bytes = 0xF3;
            out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
            offset += 1;
            break;

        case 0340:
        case 0341:
        case 0342:
            if (ins->oprs[0].segment != NO_SEG)
                errfunc(ERR_PANIC, "non-constant BSS size in pass two");
            else {
                long size = ins->oprs[0].offset << (c - 0340);
                if (size > 0)
                    out(offset, segment, NULL,
                        OUT_RESERVE + size, NO_SEG, NO_SEG);
                offset += size;
            }
            break;

        case 0370:
        case 0371:
        case 0372:
            break;

        case 0373:
            *bytes = bits == 16 ? 3 : 5;
            out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
            offset += 1;
            break;

        default:               /* can't do it by 'case' statements */
            if (c >= 0100 && c <= 0277) {       /* it's an EA */
                ea ea_data;
                int rfield;
                unsigned char *p;
                long s;

                if (c <= 0177)  /* pick rfield from operand b */
                    rfield = regval(&ins->oprs[c & 7]);
                else            /* rfield is constant */
                    rfield = c & 7;

                if (!process_ea
                    (&ins->oprs[(c >> 3) & 7], &ea_data, bits, rfield,
                     ins->forw_ref)) {
                    errfunc(ERR_NONFATAL, "invalid effective address");
                }

                p = bytes;
                *p++ = ea_data.modrm;
                if (ea_data.sib_present)
                    *p++ = ea_data.sib;

                s = p - bytes;
                out(offset, segment, bytes, OUT_RAWDATA + s,
                    NO_SEG, NO_SEG);

                switch (ea_data.bytes) {
                case 0:
                    break;
                case 1:
                    if (ins->oprs[(c >> 3) & 7].segment != NO_SEG) {
                        data = ins->oprs[(c >> 3) & 7].offset;
                        out(offset, segment, &data, OUT_ADDRESS + 1,
                            ins->oprs[(c >> 3) & 7].segment,
                            ins->oprs[(c >> 3) & 7].wrt);
                    } else {
                        *bytes = ins->oprs[(c >> 3) & 7].offset;
                        out(offset, segment, bytes, OUT_RAWDATA + 1,
                            NO_SEG, NO_SEG);
                    }
                    s++;
                    break;
                case 2:
                case 4:
                    data = ins->oprs[(c >> 3) & 7].offset;
                    out(offset, segment, &data,
                        OUT_ADDRESS + ea_data.bytes,
                        ins->oprs[(c >> 3) & 7].segment,
                        ins->oprs[(c >> 3) & 7].wrt);
                    s += ea_data.bytes;
                    break;
                }
                offset += s;
            } else
                errfunc(ERR_PANIC, "internal instruction table corrupt"
                        ": instruction code 0x%02X given", c);
        }
}

#include "regvals.c"

static int regval(operand * o)
{
    if (o->basereg < EXPR_REG_START || o->basereg >= REG_ENUM_LIMIT) {
        errfunc(ERR_PANIC, "invalid operand passed to regval()");
    }
    return regvals[o->basereg];
}

static int matches(struct itemplate *itemp, insn * instruction)
{
    int i, size[3], asize, oprs, ret;

    ret = 100;

    /*
     * Check the opcode
     */
    if (itemp->opcode != instruction->opcode)
        return 0;

    /*
     * Count the operands
     */
    if (itemp->operands != instruction->operands)
        return 0;

    /*
     * Check that no spurious colons or TOs are present
     */
    for (i = 0; i < itemp->operands; i++)
        if (instruction->oprs[i].type & ~itemp->opd[i] & (COLON | TO))
            return 0;

    /*
     * Check that the operand flags all match up
     */
    for (i = 0; i < itemp->operands; i++)
        if (itemp->opd[i] & ~instruction->oprs[i].type ||
            ((itemp->opd[i] & SIZE_MASK) &&
             ((itemp->opd[i] ^ instruction->oprs[i].type) & SIZE_MASK))) {
            if ((itemp->opd[i] & ~instruction->oprs[i].type & NON_SIZE) ||
                (instruction->oprs[i].type & SIZE_MASK))
                return 0;
            else
/*		ret = 1;   */
                return 1;
        }

    /*
     * Check operand sizes
     */
    if (itemp->flags & IF_ARMASK) {
        size[0] = size[1] = size[2] = 0;

        switch (itemp->flags & IF_ARMASK) {
        case IF_AR0:
            i = 0;
            break;
        case IF_AR1:
            i = 1;
            break;
        case IF_AR2:
            i = 2;
            break;
        default:
            break;              /* Shouldn't happen */
        }
        if (itemp->flags & IF_SB) {
            size[i] = BITS8;
        } else if (itemp->flags & IF_SW) {
            size[i] = BITS16;
        } else if (itemp->flags & IF_SD) {
            size[i] = BITS32;
        }
    } else {
        asize = 0;
        if (itemp->flags & IF_SB) {
            asize = BITS8;
            oprs = itemp->operands;
        } else if (itemp->flags & IF_SW) {
            asize = BITS16;
            oprs = itemp->operands;
        } else if (itemp->flags & IF_SD) {
            asize = BITS32;
            oprs = itemp->operands;
        }
        size[0] = size[1] = size[2] = asize;
    }

    if (itemp->flags & (IF_SM | IF_SM2)) {
        oprs = (itemp->flags & IF_SM2 ? 2 : itemp->operands);
        asize = 0;
        for (i = 0; i < oprs; i++) {
            if ((asize = itemp->opd[i] & SIZE_MASK) != 0) {
                int j;
                for (j = 0; j < oprs; j++)
                    size[j] = asize;
                break;
            }
        }
    } else {
        oprs = itemp->operands;
    }

    for (i = 0; i < itemp->operands; i++)
        if (!(itemp->opd[i] & SIZE_MASK) &&
            (instruction->oprs[i].type & SIZE_MASK & ~size[i]))
/*	    ret = 2;  */
            return 2;

⌨️ 快捷键说明

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