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

📄 assemble.c

📁 nasm的全套源代码,有些我做了些修改,以方便您更方便更容易调试成功,方便学习做编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
        case 045:
        case 046:
            length += ((ins->oprs[c - 044].addr_size ?
                        ins->oprs[c - 044].addr_size : bits) ==
                       16 ? 2 : 4);
            break;
        case 050:
        case 051:
        case 052:
            length++;
            break;
        case 060:
        case 061:
        case 062:
            length += 2;
            break;
        case 064:
        case 065:
        case 066:
            if (ins->oprs[c - 064].type & (BITS16 | BITS32))
                length += (ins->oprs[c - 064].type & BITS16) ? 2 : 4;
            else
                length += (bits == 16) ? 2 : 4;
            break;
        case 070:
        case 071:
        case 072:
            length += 4;
            break;
        case 0130:
        case 0131:
        case 0132:
            length += is_sbyte(ins, c - 0130, 16) ? 1 : 2;
            break;
        case 0133:
        case 0134:
        case 0135:
            codes += 2;
            length++;
            break;
        case 0140:
        case 0141:
        case 0142:
            length += is_sbyte(ins, c - 0140, 32) ? 1 : 4;
            break;
        case 0143:
        case 0144:
        case 0145:
            codes += 2;
            length++;
            break;
        case 0300:
        case 0301:
        case 0302:
            length += chsize(&ins->oprs[c - 0300], bits);
            break;
        case 0310:
            length += (bits == 32);
            break;
        case 0311:
            length += (bits == 16);
            break;
        case 0312:
            break;
        case 0320:
            length += (bits == 32);
            break;
        case 0321:
            length += (bits == 16);
            break;
        case 0322:
            break;
        case 0330:
            codes++, length++;
            break;
        case 0331:
        case 0332:
            break;
        case 0333:
            length++;
            break;
        case 0340:
        case 0341:
        case 0342:
            if (ins->oprs[0].segment != NO_SEG)
                errfunc(ERR_NONFATAL, "attempt to reserve non-constant"
                        " quantity of BSS space");
            else
                length += ins->oprs[0].offset << (c - 0340);
            break;
        case 0370:
        case 0371:
        case 0372:
            break;
        case 0373:
            length++;
            break;
        default:               /* can't do it by 'case' statements */
            if (c >= 0100 && c <= 0277) {       /* it's an EA */
                ea ea_data;
                if (!process_ea
                    (&ins->oprs[(c >> 3) & 7], &ea_data, bits, 0,
                     ins->forw_ref)) {
                    errfunc(ERR_NONFATAL, "invalid effective address");
                    return -1;
                } else
                    length += ea_data.size;
            } else
                errfunc(ERR_PANIC, "internal instruction table corrupt"
                        ": instruction code 0x%02X given", c);
        }
    return length;
}

static void gencode(long segment, long offset, int bits,
                    insn * ins, const char *codes, long insn_end)
{
    static char condval[] = {   /* conditional opcodes */
        0x7, 0x3, 0x2, 0x6, 0x2, 0x4, 0xF, 0xD, 0xC, 0xE, 0x6, 0x2,
        0x3, 0x7, 0x3, 0x5, 0xE, 0xC, 0xD, 0xF, 0x1, 0xB, 0x9, 0x5,
        0x0, 0xA, 0xA, 0xB, 0x8, 0x4
    };
    unsigned char c;
    unsigned char bytes[4];
    long data, size;

    while (*codes)
        switch (c = *codes++) {
        case 01:
        case 02:
        case 03:
            out(offset, segment, codes, OUT_RAWDATA + c, NO_SEG, NO_SEG);
            codes += c;
            offset += c;
            break;

        case 04:
        case 06:
            switch (ins->oprs[0].basereg) {
            case R_CS:
                bytes[0] = 0x0E + (c == 0x04 ? 1 : 0);
                break;
            case R_DS:
                bytes[0] = 0x1E + (c == 0x04 ? 1 : 0);
                break;
            case R_ES:
                bytes[0] = 0x06 + (c == 0x04 ? 1 : 0);
                break;
            case R_SS:
                bytes[0] = 0x16 + (c == 0x04 ? 1 : 0);
                break;
            default:
                errfunc(ERR_PANIC,
                        "bizarre 8086 segment register received");
            }
            out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
            offset++;
            break;

        case 05:
        case 07:
            switch (ins->oprs[0].basereg) {
            case R_FS:
                bytes[0] = 0xA0 + (c == 0x05 ? 1 : 0);
                break;
            case R_GS:
                bytes[0] = 0xA8 + (c == 0x05 ? 1 : 0);
                break;
            default:
                errfunc(ERR_PANIC,
                        "bizarre 386 segment register received");
            }
            out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
            offset++;
            break;

        case 010:
        case 011:
        case 012:
            bytes[0] = *codes++ + regval(&ins->oprs[c - 010]);
            out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
            offset += 1;
            break;

        case 017:
            bytes[0] = 0;
            out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
            offset += 1;
            break;

        case 014:
        case 015:
        case 016:
            if (ins->oprs[c - 014].offset < -128
                || ins->oprs[c - 014].offset > 127) {
                errfunc(ERR_WARNING, "signed byte value exceeds bounds");
            }

            if (ins->oprs[c - 014].segment != NO_SEG) {
                data = ins->oprs[c - 014].offset;
                out(offset, segment, &data, OUT_ADDRESS + 1,
                    ins->oprs[c - 014].segment, ins->oprs[c - 014].wrt);
            } else {
                bytes[0] = ins->oprs[c - 014].offset;
                out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
                    NO_SEG);
            }
            offset += 1;
            break;

        case 020:
        case 021:
        case 022:
            if (ins->oprs[c - 020].offset < -256
                || ins->oprs[c - 020].offset > 255) {
                errfunc(ERR_WARNING, "byte value exceeds bounds");
            }
            if (ins->oprs[c - 020].segment != NO_SEG) {
                data = ins->oprs[c - 020].offset;
                out(offset, segment, &data, OUT_ADDRESS + 1,
                    ins->oprs[c - 020].segment, ins->oprs[c - 020].wrt);
            } else {
                bytes[0] = ins->oprs[c - 020].offset;
                out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
                    NO_SEG);
            }
            offset += 1;
            break;

        case 024:
        case 025:
        case 026:
            if (ins->oprs[c - 024].offset < 0
                || ins->oprs[c - 024].offset > 255)
                errfunc(ERR_WARNING, "unsigned byte value exceeds bounds");
            if (ins->oprs[c - 024].segment != NO_SEG) {
                data = ins->oprs[c - 024].offset;
                out(offset, segment, &data, OUT_ADDRESS + 1,
                    ins->oprs[c - 024].segment, ins->oprs[c - 024].wrt);
            } else {
                bytes[0] = ins->oprs[c - 024].offset;
                out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG,
                    NO_SEG);
            }
            offset += 1;
            break;

        case 030:
        case 031:
        case 032:
            if (ins->oprs[c - 030].segment == NO_SEG &&
                ins->oprs[c - 030].wrt == NO_SEG &&
                (ins->oprs[c - 030].offset < -65536L ||
                 ins->oprs[c - 030].offset > 65535L)) {
                errfunc(ERR_WARNING, "word value exceeds bounds");
            }
            data = ins->oprs[c - 030].offset;
            out(offset, segment, &data, OUT_ADDRESS + 2,
                ins->oprs[c - 030].segment, ins->oprs[c - 030].wrt);
            offset += 2;
            break;

        case 034:
        case 035:
        case 036:
            if (ins->oprs[c - 034].type & (BITS16 | BITS32))
                size = (ins->oprs[c - 034].type & BITS16) ? 2 : 4;
            else
                size = (bits == 16) ? 2 : 4;
            data = ins->oprs[c - 034].offset;
            if (size == 2 && (data < -65536L || data > 65535L))
                errfunc(ERR_WARNING, "word value exceeds bounds");
            out(offset, segment, &data, OUT_ADDRESS + size,
                ins->oprs[c - 034].segment, ins->oprs[c - 034].wrt);
            offset += size;
            break;

        case 037:
            if (ins->oprs[0].segment == NO_SEG)
                errfunc(ERR_NONFATAL, "value referenced by FAR is not"
                        " relocatable");
            data = 0L;
            out(offset, segment, &data, OUT_ADDRESS + 2,
                outfmt->segbase(1 + ins->oprs[0].segment),
                ins->oprs[0].wrt);
            offset += 2;
            break;

        case 040:
        case 041:
        case 042:
            data = ins->oprs[c - 040].offset;
            out(offset, segment, &data, OUT_ADDRESS + 4,
                ins->oprs[c - 040].segment, ins->oprs[c - 040].wrt);
            offset += 4;
            break;

        case 044:
        case 045:
        case 046:
            data = ins->oprs[c - 044].offset;
            size = ((ins->oprs[c - 044].addr_size ?
                     ins->oprs[c - 044].addr_size : bits) == 16 ? 2 : 4);
            if (size == 2 && (data < -65536L || data > 65535L))
                errfunc(ERR_WARNING, "word value exceeds bounds");
            out(offset, segment, &data, OUT_ADDRESS + size,
                ins->oprs[c - 044].segment, ins->oprs[c - 044].wrt);
            offset += size;
            break;

        case 050:
        case 051:
        case 052:
            if (ins->oprs[c - 050].segment != segment)
                errfunc(ERR_NONFATAL,
                        "short relative jump outside segment");
            data = ins->oprs[c - 050].offset - insn_end;
            if (data > 127 || data < -128)
                errfunc(ERR_NONFATAL, "short jump is out of range");
            bytes[0] = data;
            out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
            offset += 1;
            break;

        case 060:
        case 061:
        case 062:
            if (ins->oprs[c - 060].segment != segment) {
                data = ins->oprs[c - 060].offset;
                out(offset, segment, &data,
                    OUT_REL2ADR + insn_end - offset,
                    ins->oprs[c - 060].segment, ins->oprs[c - 060].wrt);
            } else {
                data = ins->oprs[c - 060].offset - insn_end;
                out(offset, segment, &data,
                    OUT_ADDRESS + 2, NO_SEG, NO_SEG);
            }
            offset += 2;
            break;

        case 064:
        case 065:
        case 066:
            if (ins->oprs[c - 064].type & (BITS16 | BITS32))
                size = (ins->oprs[c - 064].type & BITS16) ? 2 : 4;
            else
                size = (bits == 16) ? 2 : 4;
            if (ins->oprs[c - 064].segment != segment) {
                long reltype = (size == 2 ? OUT_REL2ADR : OUT_REL4ADR);
                data = ins->oprs[c - 064].offset;
                out(offset, segment, &data, reltype + insn_end - offset,
                    ins->oprs[c - 064].segment, ins->oprs[c - 064].wrt);
            } else {

⌨️ 快捷键说明

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