assemble.c
来自「nasm早期的源代码,比较简单是学习汇编和编译原理的好例子」· C语言 代码 · 共 1,987 行 · 第 1/5 页
C
1,987 行
case 035:
case 036:
case 037:
if (ins->oprs[c - 034].type & (BITS16 | BITS32 | BITS64))
length += (ins->oprs[c - 034].type & BITS16) ? 2 : 4;
else
length += (bits == 16) ? 2 : 4;
break;
case 040:
case 041:
case 042:
case 043:
length += 4;
break;
case 044:
case 045:
case 046:
case 047:
length += ((ins->oprs[c - 044].addr_size ?
ins->oprs[c - 044].addr_size : bits) >> 3);
break;
case 050:
case 051:
case 052:
case 053:
length++;
break;
case 054:
case 055:
case 056:
case 057:
length += 8; /* MOV reg64/imm */
break;
case 060:
case 061:
case 062:
case 063:
length += 2;
break;
case 064:
case 065:
case 066:
case 067:
if (ins->oprs[c - 064].type & (BITS16 | BITS32 | BITS64))
length += (ins->oprs[c - 064].type & BITS16) ? 2 : 4;
else
length += (bits == 16) ? 2 : 4;
break;
case 070:
case 071:
case 072:
case 073:
length += 4;
break;
case 074:
case 075:
case 076:
case 077:
length += 2;
break;
case 0140:
case 0141:
case 0142:
case 0143:
length += is_sbyte(ins, c - 0140, 16) ? 1 : 2;
break;
case 0144:
case 0145:
case 0146:
case 0147:
codes += 2;
length++;
break;
case 0150:
case 0151:
case 0152:
case 0153:
length += is_sbyte(ins, c - 0150, 32) ? 1 : 4;
break;
case 0154:
case 0155:
case 0156:
case 0157:
codes += 2;
length++;
break;
case 0160:
case 0161:
case 0162:
case 0163:
length++;
ins->rex |= REX_D;
ins->drexdst = regval(&ins->oprs[c & 3]);
break;
case 0164:
case 0165:
case 0166:
case 0167:
length++;
ins->rex |= REX_D|REX_OC;
ins->drexdst = regval(&ins->oprs[c & 3]);
break;
case 0170:
length++;
break;
case 0171:
break;
case 0300:
case 0301:
case 0302:
case 0303:
break;
case 0310:
if (bits == 64)
return -1;
length += (bits != 16) && !has_prefix(ins,P_A16);
break;
case 0311:
length += (bits != 32) && !has_prefix(ins,P_A32);
break;
case 0312:
break;
case 0313:
if (bits != 64 || has_prefix(ins,P_A16) || has_prefix(ins,P_A32))
return -1;
break;
case 0320:
length += (bits != 16);
break;
case 0321:
length += (bits == 16);
break;
case 0322:
break;
case 0323:
rex_mask &= ~REX_W;
break;
case 0324:
ins->rex |= REX_W;
break;
case 0330:
codes++, length++;
break;
case 0331:
break;
case 0332:
case 0333:
length++;
break;
case 0334:
assert_no_prefix(ins, P_LOCK);
ins->rex |= REX_L;
break;
case 0335:
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 0364:
case 0365:
break;
case 0366:
case 0367:
length++;
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;
int rfield;
int32_t rflags;
ea_data.rex = 0; /* Ensure ea.REX is initially 0 */
if (c <= 0177) {
/* pick rfield from operand b */
rflags = regflag(&ins->oprs[c & 7]);
rfield = regvals[ins->oprs[c & 7].basereg];
} else {
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");
return -1;
} else {
ins->rex |= ea_data.rex;
length += ea_data.size;
}
} else
errfunc(ERR_PANIC, "internal instruction table corrupt"
": instruction code 0x%02X given", c);
}
ins->rex &= rex_mask;
if (ins->rex & REX_D) {
if (ins->rex & REX_H) {
errfunc(ERR_NONFATAL, "cannot use high register in drex instruction");
return -1;
}
if (bits != 64 && ((ins->rex & (REX_W|REX_X|REX_B)) ||
ins->drexdst > 7)) {
errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
return -1;
}
length++;
} else if (ins->rex & REX_REAL) {
if (ins->rex & REX_H) {
errfunc(ERR_NONFATAL, "cannot use high register in rex instruction");
return -1;
} else if (bits == 64 ||
((ins->rex & REX_L) &&
!(ins->rex & (REX_P|REX_W|REX_X|REX_B)) &&
cpu >= IF_X86_64)) {
length++;
} else {
errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode");
return -1;
}
}
return length;
}
#define EMIT_REX() \
if (!(ins->rex & REX_D) && (ins->rex & REX_REAL) && (bits == 64)) { \
ins->rex = (ins->rex & REX_REAL)|REX_P; \
out(offset, segment, &ins->rex, OUT_RAWDATA+1, NO_SEG, NO_SEG); \
ins->rex = 0; \
offset += 1; \
}
static void gencode(int32_t segment, int32_t offset, int bits,
insn * ins, const char *codes, int32_t 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
};
uint8_t c;
uint8_t bytes[4];
int32_t size;
int64_t data;
while (*codes)
switch (c = *codes++) {
case 01:
case 02:
case 03:
EMIT_REX();
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:
case 013:
EMIT_REX();
bytes[0] = *codes++ + ((regval(&ins->oprs[c - 010])) & 7);
out(offset, segment, bytes, OUT_RAWDATA + 1, NO_SEG, NO_SEG);
offset += 1;
break;
case 014:
case 015:
case 016:
case 017:
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:
case 023:
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:
case 027:
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:
case 033:
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:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?