📄 assemble.c
字号:
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 + -