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

📄 assemble.c

📁 汇编编译器的最新版本的源码.买了自己动手写操作系统这本书的人一定要下
💻 C
📖 第 1 页 / 共 5 页
字号:
                    OUT_REL2ADR, insn_end - offset,
                    opx->segment, opx->wrt);
            } else {
                data = opx->offset - insn_end;
                out(offset, segment, &data,
                    OUT_ADDRESS, 2, NO_SEG, NO_SEG);
            }
            offset += 2;
            break;

	case4(064):
            if (opx->type & (BITS16 | BITS32 | BITS64))
                size = (opx->type & BITS16) ? 2 : 4;
            else
                size = (bits == 16) ? 2 : 4;
            if (opx->segment != segment) {
                data = opx->offset;
                out(offset, segment, &data,
		    size == 2 ? OUT_REL2ADR : OUT_REL4ADR,
		    insn_end - offset, opx->segment, opx->wrt);
            } else {
                data = opx->offset - insn_end;
                out(offset, segment, &data,
                    OUT_ADDRESS, size, NO_SEG, NO_SEG);
            }
            offset += size;
            break;

	case4(070):
            if (opx->segment != segment) {
                data = opx->offset;
                out(offset, segment, &data,
                    OUT_REL4ADR, insn_end - offset,
                    opx->segment, opx->wrt);
            } else {
                data = opx->offset - insn_end;
                out(offset, segment, &data,
                    OUT_ADDRESS, 4, NO_SEG, NO_SEG);
            }
            offset += 4;
            break;

	case4(074):
            if (opx->segment == NO_SEG)
                errfunc(ERR_NONFATAL, "value referenced by FAR is not"
                        " relocatable");
	    data = 0;
            out(offset, segment, &data, OUT_ADDRESS, 2,
                outfmt->segbase(1 + opx->segment),
                opx->wrt);
            offset += 2;
            break;

	case4(0140):
            data = opx->offset;
	    warn_overflow(2, opx);
            if (is_sbyte16(opx)) {
                bytes[0] = data;
                out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
                    NO_SEG);
                offset++;
            } else {
                out(offset, segment, &data, OUT_ADDRESS, 2,
                    opx->segment, opx->wrt);
                offset += 2;
            }
            break;

	case4(0144):
	    EMIT_REX();
            bytes[0] = *codes++;
            if (is_sbyte16(opx))
                bytes[0] |= 2;  /* s-bit */
            out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
            offset++;
            break;

	case4(0150):
            data = opx->offset;
	    warn_overflow(4, opx);
            if (is_sbyte32(opx)) {
                bytes[0] = data;
                out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
                    NO_SEG);
                offset++;
            } else {
                out(offset, segment, &data, OUT_ADDRESS, 4,
                    opx->segment, opx->wrt);
                offset += 4;
            }
            break;

	case4(0154):
	    EMIT_REX();
            bytes[0] = *codes++;
            if (is_sbyte32(opx))
                bytes[0] |= 2;  /* s-bit */
            out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
            offset++;
            break;

	case4(0160):
	case4(0164):
	    break;

	case 0171:
	    bytes[0] =
		(ins->drexdst << 4) |
		(ins->rex & REX_OC ? 0x08 : 0) |
		(ins->rex & (REX_R|REX_X|REX_B));
	    ins->rex = 0;
            out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
	    offset++;
	    break;

	case 0172:
	    c = *codes++;
	    opx = &ins->oprs[c >> 3];
	    bytes[0] = nasm_regvals[opx->basereg] << 4;
	    opx = &ins->oprs[c & 7];
	    if (opx->segment != NO_SEG || opx->wrt != NO_SEG) {
		errfunc(ERR_NONFATAL,
			"non-absolute expression not permitted as argument %d",
			c & 7);
	    } else {
		if (opx->offset & ~15) {
		    errfunc(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV,
			    "four-bit argument exceeds bounds");
		}
		bytes[0] |= opx->offset & 15;
	    }
	    out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
	    offset++;
	    break;

	case 0173:
	    c = *codes++;
	    opx = &ins->oprs[c >> 4];
	    bytes[0] = nasm_regvals[opx->basereg] << 4;
	    bytes[0] |= c & 15;
	    out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
	    offset++;
	    break;

	case 0174:
	    c = *codes++;
	    opx = &ins->oprs[c];
	    bytes[0] = nasm_regvals[opx->basereg] << 4;
	    out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
	    offset++;
	    break;

	case4(0250):
            data = opx->offset;
	    if (opx->wrt == NO_SEG && opx->segment == NO_SEG &&
		(int32_t)data != (int64_t)data) {
		errfunc(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV,
			"signed dword immediate exceeds bounds");
	    }
            if (is_sbyte32(opx)) {
                bytes[0] = data;
                out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
                    NO_SEG);
                offset++;
            } else {
                out(offset, segment, &data, OUT_ADDRESS, 4,
                    opx->segment, opx->wrt);
                offset += 4;
            }
            break;

	case4(0254):
            data = opx->offset;
	    if (opx->wrt == NO_SEG && opx->segment == NO_SEG &&
		(int32_t)data != (int64_t)data) {
		errfunc(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV,
			"signed dword immediate exceeds bounds");
	    }
	    out(offset, segment, &data, OUT_ADDRESS, 4,
		opx->segment, opx->wrt);
	    offset += 4;
            break;

	case4(0260):
	case 0270:
	    codes += 2;
	    if (ins->vex_m != 1 || (ins->rex & (REX_W|REX_X|REX_B))) {
		bytes[0] = 0xc4;
		bytes[1] = ins->vex_m | ((~ins->rex & 7) << 5);
		bytes[2] = ((ins->rex & REX_W) << (7-3)) |
		    ((~ins->drexdst & 15)<< 3) | (ins->vex_wlp & 07);
		out(offset, segment, &bytes, OUT_RAWDATA, 3, NO_SEG, NO_SEG);
		offset += 3;
	    } else {
		bytes[0] = 0xc5;
		bytes[1] = ((~ins->rex & REX_R) << (7-2)) |
		    ((~ins->drexdst & 15) << 3) | (ins->vex_wlp & 07);
		out(offset, segment, &bytes, OUT_RAWDATA, 2, NO_SEG, NO_SEG);
		offset += 2;
	    }
	    break;

	case4(0274):
	{
	    uint64_t uv, um;
	    int s;

	    if (ins->rex & REX_W)
		s = 64;
	    else if (ins->prefixes[PPS_OSIZE] == P_O16)
		s = 16;
	    else if (ins->prefixes[PPS_OSIZE] == P_O32)
		s = 32;
	    else
		s = bits;

	    um = (uint64_t)2 << (s-1);
	    uv = opx->offset;

	    if (uv > 127 && uv < (uint64_t)-128 &&
		(uv < um-128 || uv > um-1)) {
                errfunc(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV,
			"signed byte value exceeds bounds");
	    }
            if (opx->segment != NO_SEG) {
                data = uv;
                out(offset, segment, &data, OUT_ADDRESS, 1,
                    opx->segment, opx->wrt);
            } else {
                bytes[0] = uv;
                out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
                    NO_SEG);
            }
            offset += 1;
            break;
	}

	case4(0300):
            break;

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

        case 0311:
            if (bits != 32 && !has_prefix(ins, PPS_ASIZE, P_A32)) {
                *bytes = 0x67;
                out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
                offset += 1;
            } else
                offset += 0;
            break;

        case 0312:
            break;

        case 0313:
            ins->rex = 0;
            break;

	case4(0314):
	    break;

        case 0320:
            if (bits != 16) {
                *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:
        case 0323:
            break;

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

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

        case 0331:
            break;

	case 0332:
        case 0333:
            *bytes = c - 0332 + 0xF2;
            out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
            offset += 1;
            break;

        case 0334:
            if (ins->rex & REX_R) {
                *bytes = 0xF0;
                out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
                offset += 1;
            }
            ins->rex &= ~(REX_L|REX_R);
            break;

        case 0335:
	    break;

        case 0336:
        case 0337:
	    break;

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

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

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

	case 0360:
	    break;

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

	case 0362:
	case 0363:
	    bytes[0] = c - 0362 + 0xf2;
            out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
            offset += 1;
	    break;

	case 0364:
	case 0365:
	    break;

        case 0366:
	case 0367:
            *bytes = c - 0366 + 0x66;
            out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
            offset += 1;
            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;

	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;
                uint8_t *p;
                int32_t s;
		enum out_type type;

⌨️ 快捷键说明

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