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

📄 assemble.c

📁 汇编编译器的最新版本的源码.买了自己动手写操作系统这本书的人一定要下
💻 C
📖 第 1 页 / 共 5 页
字号:
            length += is_sbyte32(opx) ? 1 : 4;
            break;

	case4(0154):
            codes++;
            length++;
            break;

	case4(0160):
	    length++;
	    ins->rex |= REX_D;
	    ins->drexdst = regval(opx);
	    break;

	case4(0164):
	    length++;
	    ins->rex |= REX_D|REX_OC;
	    ins->drexdst = regval(opx);
	    break;

	case 0171:
	    break;

	case 0172:
	case 0173:
	case 0174:
	    codes++;
	    length++;
	    break;

	case4(0250):
            length += is_sbyte32(opx) ? 1 : 4;
            break;

	case4(0254):
	    length += 4;
	    break;

	case4(0260):
	    ins->rex |= REX_V;
	    ins->drexdst = regval(opx);
	    ins->vex_m = *codes++;
	    ins->vex_wlp = *codes++;
	    break;

	case 0270:
	    ins->rex |= REX_V;
	    ins->drexdst = 0;
	    ins->vex_m = *codes++;
	    ins->vex_wlp = *codes++;
	    break;

	case4(0274):
            length++;
            break;

	case4(0300):
            break;

        case 0310:
	    if (bits == 64)
		return -1;
            length += (bits != 16) && !has_prefix(ins, PPS_ASIZE, P_A16);
            break;

        case 0311:
            length += (bits != 32) && !has_prefix(ins, PPS_ASIZE, P_A32);
            break;

        case 0312:
            break;

        case 0313:
	    if (bits != 64 || has_prefix(ins, PPS_ASIZE, P_A16) ||
		has_prefix(ins, PPS_ASIZE, P_A32))
		return -1;
            break;

	case4(0314):
	    break;

        case 0320:
            length += (bits != 16);
            break;

        case 0321:
            length += (bits == 16);
            break;

        case 0322:
            break;

        case 0323:
            rex_mask &= ~REX_W;
            break;

        case 0324:
	    ins->rex |= REX_W;
            break;

        case 0330:
            codes++, length++;
            break;

        case 0331:
            break;

        case 0332:
        case 0333:
            length++;
            break;

	case 0334:
	    ins->rex |= REX_L;
	    break;

        case 0335:
	    break;

	case 0336:
	    if (!ins->prefixes[PPS_LREP])
		ins->prefixes[PPS_LREP] = P_REP;
	    break;

	case 0337:
	    if (!ins->prefixes[PPS_LREP])
		ins->prefixes[PPS_LREP] = P_REPNE;
	    break;

        case 0340:
            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;
            break;

	case4(0344):
            length++;
            break;

	case 0360:
	    break;

	case 0361:
	case 0362:
	case 0363:
	    length++;
	    break;

	case 0364:
	case 0365:
	    break;

        case 0366:
        case 0367:
	    length++;
	    break;

        case 0370:
        case 0371:
        case 0372:
            break;

        case 0373:
            length++;
            break;

	case4(0100):
	case4(0110):
	case4(0120):
	case4(0130):
	case4(0200):
	case4(0204):
	case4(0210):
	case4(0214):
	case4(0220):
	case4(0224):
	case4(0230):
	case4(0234):
	    {
                ea ea_data;
                int rfield;
		int32_t rflags;
                ea_data.rex = 0;           /* Ensure ea.REX is initially 0 */

		if (c <= 0177) {
		    /* pick rfield from operand b */
		    rflags = regflag(&ins->oprs[c & 7]);
		    rfield = nasm_regvals[ins->oprs[c & 7].basereg];
		} else {
		    rflags = 0;
		    rfield = c & 7;
		}

                if (!process_ea
                    (&ins->oprs[(c >> 3) & 7], &ea_data, bits,
		     ins->addr_size, rfield, rflags)) {
                    errfunc(ERR_NONFATAL, "invalid effective address");
                    return -1;
                } else {
		    ins->rex |= ea_data.rex;
                    length += ea_data.size;
                }
	    }
	    break;

	default:
	    errfunc(ERR_PANIC, "internal instruction table corrupt"
		    ": instruction code 0x%02X given", c);
	    break;
	}
    }

    ins->rex &= rex_mask;

    if (ins->rex & REX_V) {
	int bad32 = REX_R|REX_W|REX_X|REX_B;

	if (ins->rex & REX_H) {
	    errfunc(ERR_NONFATAL, "cannot use high register in vex instruction");
	    return -1;
	}
	switch (ins->vex_wlp & 030) {
	case 000:
	case 020:
	    ins->rex &= ~REX_W;
	    break;
	case 010:
	    ins->rex |= REX_W;
	    bad32 &= ~REX_W;
	    break;
	case 030:
	    /* Follow REX_W */
	    break;
	}

	if (bits != 64 && ((ins->rex & bad32) || ins->drexdst > 7)) {
	    errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
	    return -1;
	}
	if (ins->vex_m != 1 || (ins->rex & (REX_W|REX_R|REX_B)))
	    length += 3;
	else
	    length += 2;
    } else if (ins->rex & REX_D) {
	if (ins->rex & REX_H) {
	    errfunc(ERR_NONFATAL, "cannot use high register in drex instruction");
	    return -1;
	}
	if (bits != 64 && ((ins->rex & (REX_R|REX_W|REX_X|REX_B)) ||
			   ins->drexdst > 7)) {
	    errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
	    return -1;
	}
	length++;
    } else if (ins->rex & REX_REAL) {
	if (ins->rex & REX_H) {
	    errfunc(ERR_NONFATAL, "cannot use high register in rex instruction");
	    return -1;
	} else if (bits == 64) {
	    length++;
	} else if ((ins->rex & REX_L) &&
		   !(ins->rex & (REX_P|REX_W|REX_X|REX_B)) &&
		   cpu >= IF_X86_64) {
	    /* LOCK-as-REX.R */
	    assert_no_prefix(ins, PPS_LREP);
	    length++;
	} else {
	    errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
	    return -1;
	}
    }

    return length;
}

#define EMIT_REX()							\
    if (!(ins->rex & (REX_D|REX_V)) && (ins->rex & REX_REAL) && (bits == 64)) { \
	ins->rex = (ins->rex & REX_REAL)|REX_P;				\
	out(offset, segment, &ins->rex, OUT_RAWDATA, 1, NO_SEG, NO_SEG); \
	ins->rex = 0;							\
	offset += 1; \
    }

static void gencode(int32_t segment, int64_t offset, int bits,
                    insn * ins, const struct itemplate *temp,
		    int64_t 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
    };
    uint8_t c;
    uint8_t bytes[4];
    int64_t size;
    int64_t data;
    struct operand *opx;
    const uint8_t *codes = temp->code;

    while (*codes) {
	c = *codes++;
	opx = &ins->oprs[c & 3];
        switch (c) {
        case 01:
        case 02:
        case 03:
	    EMIT_REX();
            out(offset, segment, codes, OUT_RAWDATA, c, NO_SEG, NO_SEG);
            codes += c;
            offset += c;
            break;

	case4(010):
	    EMIT_REX();
            bytes[0] = *codes++ + ((regval(opx)) & 7);
            out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
            offset += 1;
            break;

	case4(014):
	    /* The test for BITS8 and SBYTE here is intended to avoid
	       warning on optimizer actions due to SBYTE, while still
	       warn on explicit BYTE directives.  Also warn, obviously,
	       if the optimizer isn't enabled. */
            if (((opx->type & BITS8) ||
		 !(opx->type & temp->opd[c & 3] & BYTENESS)) &&
		(opx->offset < -128 || opx->offset > 127)) {
                errfunc(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV,
			"signed byte value exceeds bounds");
	    }
            if (opx->segment != NO_SEG) {
                data = opx->offset;
                out(offset, segment, &data, OUT_ADDRESS, 1,
                    opx->segment, opx->wrt);
            } else {
                bytes[0] = opx->offset;
                out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
                    NO_SEG);
            }
            offset += 1;
            break;

	case4(020):
            if (opx->offset < -256 || opx->offset > 255) {
                errfunc(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV,
			"byte value exceeds bounds");
            }
            if (opx->segment != NO_SEG) {
                data = opx->offset;
                out(offset, segment, &data, OUT_ADDRESS, 1,
                    opx->segment, opx->wrt);
            } else {
                bytes[0] = opx->offset;
                out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
                    NO_SEG);
            }
            offset += 1;
            break;

	case4(024):
            if (opx->offset < 0 || opx->offset > 255)
                errfunc(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV,
			"unsigned byte value exceeds bounds");
            if (opx->segment != NO_SEG) {
                data = opx->offset;
                out(offset, segment, &data, OUT_ADDRESS, 1,
                    opx->segment, opx->wrt);
            } else {
                bytes[0] = opx->offset;
                out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
                    NO_SEG);
            }
            offset += 1;
            break;

	case4(030):
	    warn_overflow(2, opx);
            data = opx->offset;
            out(offset, segment, &data, OUT_ADDRESS, 2,
                opx->segment, opx->wrt);
            offset += 2;
            break;

	case4(034):
            if (opx->type & (BITS16 | BITS32))
                size = (opx->type & BITS16) ? 2 : 4;
            else
                size = (bits == 16) ? 2 : 4;
	    warn_overflow(size, opx);
            data = opx->offset;
            out(offset, segment, &data, OUT_ADDRESS, size,
                opx->segment, opx->wrt);
            offset += size;
            break;

	case4(040):
	    warn_overflow(4, opx);
            data = opx->offset;
            out(offset, segment, &data, OUT_ADDRESS, 4,
                opx->segment, opx->wrt);
            offset += 4;
            break;

	case4(044):
            data = opx->offset;
            size = ins->addr_size >> 3;
	    warn_overflow(size, opx);
            out(offset, segment, &data, OUT_ADDRESS, size,
                opx->segment, opx->wrt);
            offset += size;
            break;

	case4(050):
            if (opx->segment != segment)
                errfunc(ERR_NONFATAL,
                        "short relative jump outside segment");
            data = opx->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;

	case4(054):
            data = (int64_t)opx->offset;
            out(offset, segment, &data, OUT_ADDRESS, 8,
                opx->segment, opx->wrt);
            offset += 8;
            break;

	case4(060):
            if (opx->segment != segment) {
                data = opx->offset;
                out(offset, segment, &data,

⌨️ 快捷键说明

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