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

📄 assemble.c

📁 一个免费的汇编语言编译器的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		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 {
		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++;

⌨️ 快捷键说明

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