📄 assemble.c
字号:
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++;
break;
case 2:
case 4:
data = ins->oprs[(c >> 3) & 7].offset;
out(offset, segment, &data,
OUT_ADDRESS + ea_data.bytes,
ins->oprs[(c >> 3) & 7].segment,
ins->oprs[(c >> 3) & 7].wrt);
s += ea_data.bytes;
break;
}
offset += s;
} else
errfunc(ERR_PANIC, "internal instruction table corrupt"
": instruction code 0x%02X given", c);
}
}
#include "regvals.c"
static int regval(operand * o)
{
if (o->basereg < EXPR_REG_START || o->basereg >= REG_ENUM_LIMIT) {
errfunc(ERR_PANIC, "invalid operand passed to regval()");
}
return regvals[o->basereg];
}
static int matches(struct itemplate *itemp, insn * instruction)
{
int i, size[3], asize, oprs, ret;
ret = 100;
/*
* Check the opcode
*/
if (itemp->opcode != instruction->opcode)
return 0;
/*
* Count the operands
*/
if (itemp->operands != instruction->operands)
return 0;
/*
* Check that no spurious colons or TOs are present
*/
for (i = 0; i < itemp->operands; i++)
if (instruction->oprs[i].type & ~itemp->opd[i] & (COLON | TO))
return 0;
/*
* Check that the operand flags all match up
*/
for (i = 0; i < itemp->operands; i++)
if (itemp->opd[i] & ~instruction->oprs[i].type ||
((itemp->opd[i] & SIZE_MASK) &&
((itemp->opd[i] ^ instruction->oprs[i].type) & SIZE_MASK))) {
if ((itemp->opd[i] & ~instruction->oprs[i].type & NON_SIZE) ||
(instruction->oprs[i].type & SIZE_MASK))
return 0;
else
/* ret = 1; */
return 1;
}
/*
* Check operand sizes
*/
if (itemp->flags & IF_ARMASK) {
size[0] = size[1] = size[2] = 0;
switch (itemp->flags & IF_ARMASK) {
case IF_AR0:
i = 0;
break;
case IF_AR1:
i = 1;
break;
case IF_AR2:
i = 2;
break;
default:
break; /* Shouldn't happen */
}
if (itemp->flags & IF_SB) {
size[i] = BITS8;
} else if (itemp->flags & IF_SW) {
size[i] = BITS16;
} else if (itemp->flags & IF_SD) {
size[i] = BITS32;
}
} else {
asize = 0;
if (itemp->flags & IF_SB) {
asize = BITS8;
oprs = itemp->operands;
} else if (itemp->flags & IF_SW) {
asize = BITS16;
oprs = itemp->operands;
} else if (itemp->flags & IF_SD) {
asize = BITS32;
oprs = itemp->operands;
}
size[0] = size[1] = size[2] = asize;
}
if (itemp->flags & (IF_SM | IF_SM2)) {
oprs = (itemp->flags & IF_SM2 ? 2 : itemp->operands);
asize = 0;
for (i = 0; i < oprs; i++) {
if ((asize = itemp->opd[i] & SIZE_MASK) != 0) {
int j;
for (j = 0; j < oprs; j++)
size[j] = asize;
break;
}
}
} else {
oprs = itemp->operands;
}
for (i = 0; i < itemp->operands; i++)
if (!(itemp->opd[i] & SIZE_MASK) &&
(instruction->oprs[i].type & SIZE_MASK & ~size[i]))
/* ret = 2; */
return 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -