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

📄 assemble.c

📁 nasm早期的源代码,比较简单是学习汇编和编译原理的好例子
💻 C
📖 第 1 页 / 共 5 页
字号:
        case 035:
        case 036:
	case 037:
            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 040:
        case 041:
        case 042:
	case 043:
            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:
	case 047:
            data = ins->oprs[c - 044].offset;
            size = ((ins->oprs[c - 044].addr_size ?
                     ins->oprs[c - 044].addr_size : bits) >> 3);
            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:
	case 053:
            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 054:
        case 055:
        case 056:
	case 057:
            data = (int64_t)ins->oprs[c - 054].offset;
            out(offset, segment, &data, OUT_ADDRESS + 8,
                ins->oprs[c - 054].segment, ins->oprs[c - 054].wrt);
            offset += 8;
            break;

        case 060:
        case 061:
        case 062:
	case 063:
            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:
	case 067:
            if (ins->oprs[c - 064].type & (BITS16 | BITS32 | BITS64))
                size = (ins->oprs[c - 064].type & BITS16) ? 2 : 4;
            else
                size = (bits == 16) ? 2 : 4;
            if (ins->oprs[c - 064].segment != segment) {
                int32_t 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 {
                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:
	case 073:
            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 074:
        case 075:
        case 076:
        case 077:
            if (ins->oprs[c - 074].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[c - 074].segment),
                ins->oprs[c - 074].wrt);
            offset += 2;
            break;

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

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

        case 0150:
        case 0151:
        case 0152:
	case 0153:
            data = ins->oprs[c - 0150].offset;
            if (is_sbyte(ins, c - 0150, 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 - 0150].segment, ins->oprs[c - 0150].wrt);
                offset += 4;
            }
            break;

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

	case 0160:
	case 0161:
	case 0162:
	case 0163:
	case 0164:
	case 0165:
	case 0166:
	case 0167:
	    break;

        case 0170:
	    EMIT_REX();
            bytes[0] = 0;
            out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
            offset += 1;
            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 0300:
        case 0301:
        case 0302:
        case 0303:
            break;

        case 0310:
            if (bits == 32 && !has_prefix(ins,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,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;

        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 0340:
        case 0341:
        case 0342:
            if (ins->oprs[0].segment != NO_SEG)
                errfunc(ERR_PANIC, "non-constant BSS size in pass two");
            else {
                int32_t 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 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;

        default:               /* can't do it by 'case' statements */
            if (c >= 0100 && c <= 0277) {       /* it's an EA */
                ea ea_data;
                int rfield;
		int32_t rflags;
                uint8_t *p;
                int32_t s;
                
                if (c <= 0177) {
		    /* pick rfield from operand b */
		    rflags = regflag(&ins->oprs[c & 7]);
                    rfield = regvals[ins->oprs[c & 7].basereg];
		} else {
		    /* rfield is constant */
		    rflags = 0;
                    rfield = c & 7;
		}

                if (!process_ea
                    (&ins->oprs[(c >> 3) & 7], &ea_data, bits,
		     rfield, rflags, ins->forw_ref)) {
                    errfunc(ERR_NONFATAL, "invalid effective address");
                }
                            
                p = bytes;
                *p++ = ea_data.modrm;
                if (ea_data.sib_present)
                    *p++ = ea_data.sib;

		/* DREX suffixes come between the SIB and the displacement */
		if (ins->rex & REX_D) {
		    *p++ =
			(ins->drexdst << 4) |
			(ins->rex & REX_OC ? 0x08 : 0) |
			(ins->rex & (REX_R|REX_X|REX_B));
		    ins->rex = 0;
		}

                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;

⌨️ 快捷键说明

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