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