📄 assemble.c
字号:
case 045:
case 046:
length += ((ins->oprs[c - 044].addr_size ?
ins->oprs[c - 044].addr_size : bits) ==
16 ? 2 : 4);
break;
case 050:
case 051:
case 052:
length++;
break;
case 060:
case 061:
case 062:
length += 2;
break;
case 064:
case 065:
case 066:
if (ins->oprs[c - 064].type & (BITS16 | BITS32))
length += (ins->oprs[c - 064].type & BITS16) ? 2 : 4;
else
length += (bits == 16) ? 2 : 4;
break;
case 070:
case 071:
case 072:
length += 4;
break;
case 0130:
case 0131:
case 0132:
length += is_sbyte(ins, c - 0130, 16) ? 1 : 2;
break;
case 0133:
case 0134:
case 0135:
codes += 2;
length++;
break;
case 0140:
case 0141:
case 0142:
length += is_sbyte(ins, c - 0140, 32) ? 1 : 4;
break;
case 0143:
case 0144:
case 0145:
codes += 2;
length++;
break;
case 0300:
case 0301:
case 0302:
length += chsize(&ins->oprs[c - 0300], bits);
break;
case 0310:
length += (bits == 32);
break;
case 0311:
length += (bits == 16);
break;
case 0312:
break;
case 0320:
length += (bits == 32);
break;
case 0321:
length += (bits == 16);
break;
case 0322:
break;
case 0330:
codes++, length++;
break;
case 0331:
case 0332:
break;
case 0333:
length++;
break;
case 0340:
case 0341:
case 0342:
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 << (c - 0340);
break;
case 0370:
case 0371:
case 0372:
break;
case 0373:
length++;
break;
default: /* can't do it by 'case' statements */
if (c >= 0100 && c <= 0277) { /* it's an EA */
ea ea_data;
if (!process_ea
(&ins->oprs[(c >> 3) & 7], &ea_data, bits, 0,
ins->forw_ref)) {
errfunc(ERR_NONFATAL, "invalid effective address");
return -1;
} else
length += ea_data.size;
} else
errfunc(ERR_PANIC, "internal instruction table corrupt"
": instruction code 0x%02X given", c);
}
return length;
}
static void gencode(long segment, long offset, int bits,
insn * ins, const char *codes, long 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
};
unsigned char c;
unsigned char bytes[4];
long data, size;
while (*codes)
switch (c = *codes++) {
case 01:
case 02:
case 03:
out(offset, segment, codes, OUT_RAWDATA + c, NO_SEG, NO_SEG);
codes += c;
offset += c;
break;
case 04:
case 06:
switch (ins->oprs[0].basereg) {
case R_CS:
bytes[0] = 0x0E + (c == 0x04 ? 1 : 0);
break;
case R_DS:
bytes[0] = 0x1E + (c == 0x04 ? 1 : 0);
break;
case R_ES:
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 {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -