📄 outas386.c
字号:
/*
* append the length field to an instruction.
*/
{
if (l < 0)
l = - l;
switch(l) {
case BESZ_BOOL:
case BESZ_BYTE:
case BESZ_WORD:
case BESZ_DWORD:
case BESZ_QWORD:
case BESZ_FLOAT:
case BESZ_IFLOAT:
case BESZ_CFLOAT:
case BESZ_DOUBLE:
case BESZ_IDOUBLE:
case BESZ_CDOUBLE:
case 0:
break;
default:
DIAG("illegal length field.");
}
}
//-------------------------------------------------------------------------
void putsizedreg(char *string, int reg, int size)
{
static char *byteregs[] =
{
"AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH"
};
static char *wordregs[] =
{
"AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI"
};
static char *longregs[] =
{
"EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI"
};
if (size < 0)
size = - size;
if (size == 4)
oprintf(outputFile, string, longregs[reg]);
else if (size == 1 || size == 5)
{
oprintf(outputFile, string, byteregs[reg]);
}
else
oprintf(outputFile, string, wordregs[reg]);
}
//-------------------------------------------------------------------------
void pointersize(int size)
{
if (prm_nasm && skipsize)
return ;
if (size < 0)
size = - size;
/* if (needpointer)
*/switch (size)
{
case BESZ_LDOUBLE:
case BESZ_ILDOUBLE:
if (prm_nasm)
oprintf(outputFile, "TWORD ");
else
oprintf(outputFile, "TBYTE ");
break;
case BESZ_QWORD:
case BESZ_DOUBLE:
case BESZ_IDOUBLE:
// should never happen
oprintf(outputFile, "QWORD ");
break;
case BESZ_FLOAT:
case BESZ_IFLOAT:
if (!uses_float)
{
if (prm_nasm)
oprintf(outputFile, "DWORD FAR ");
else
oprintf(outputFile, "FWORD ");
break;
}
case BESZ_DWORD:
oprintf(outputFile, "DWORD ");
break;
case BESZ_WORD:
oprintf(outputFile, "WORD ");
break;
case BESZ_BOOL:
case BESZ_BYTE:
oprintf(outputFile, "BYTE ");
break;
case 0:
/* for NASM with certain FP ops */
break;
default:
DIAG("Bad pointer");
}
if (!prm_nasm && size)
oprintf(outputFile, "PTR ");
}
//-------------------------------------------------------------------------
void putseg(int seg, int usecolon)
{
if (!seg)
return ;
seg -= 1;
seg <<= 1;
oputc(segregs[seg], outputFile);
oputc(segregs[seg + 1], outputFile);
if (usecolon)
oputc(':', outputFile);
}
//-------------------------------------------------------------------------
int islabeled(ENODE *n)
{
int rv = 0;
switch (n->nodetype)
{
case en_add:
case en_addstruc:
rv |= islabeled(n->v.p[0]);
rv |= islabeled(n->v.p[1]);
break;
case en_icon:
case en_ccon:
case en_cucon:
case en_lcon:
case en_lucon:
case en_iucon:
case en_boolcon:
return 0;
case en_labcon:
case en_nacon:
case en_autocon:
case en_absacon:
case en_nalabcon:
case en_napccon:
return 1;
default:
DIAG("Unexpected node type in islabeled");
break;
}
return rv;
}
//-------------------------------------------------------------------------
void putamode(AMODE *ap)
/*
* output a general addressing mode.
*/
{
int oldnasm, l;
switch (ap->mode)
{
case am_seg:
putseg(ap->seg, 0);
break;
case am_screg:
oprintf(outputFile, "CR%d", ap->preg);
break;
case am_sdreg:
oprintf(outputFile, "DR%d", ap->preg);
break;
case am_streg:
oprintf(outputFile, "TR%d", ap->preg);
break;
case am_immed:
if (ap->length > 0 && islabeled(ap->offset))
{
if (!prm_nasm)
oprintf(outputFile, "OFFSET ");
else if (!nosize)
oprintf(outputFile, "DWORD ");
}
else if (prm_nasm && addsize)
pointersize(ap->length);
putconst(ap->offset);
break;
case am_direct:
pointersize(ap->length);
if (!prm_nasm)
putseg(ap->seg, TRUE);
oputc('[', outputFile);
oldnasm = prm_nasm;
if (prm_nasm)
putseg(ap->seg, TRUE);
prm_nasm = TRUE;
putconst(ap->offset);
oputc(']', outputFile);
prm_nasm = oldnasm;
break;
case am_dreg:
putsizedreg("%s", ap->preg, ap->length);
break;
case am_freg:
if (prm_nasm)
oprintf(outputFile, "ST%d", ap->preg);
else
oprintf(outputFile, "ST(%d)", ap->preg);
break;
case am_indisp:
pointersize(ap->length);
if (!prm_nasm)
putseg(ap->seg, TRUE);
oputc('[', outputFile);
if (prm_nasm)
putseg(ap->seg, TRUE);
putsizedreg("%s", ap->preg, 4);
if (ap->offset)
{
oputc('+', outputFile);
putconst(ap->offset);
}
oputc(']', outputFile);
break;
case am_indispscale:
{
int scale = 1, t = ap->scale;
while (t--)
scale <<= 1;
pointersize(ap->length);
if (!prm_nasm)
putseg(ap->seg, TRUE);
oputc('[', outputFile);
if (prm_nasm)
putseg(ap->seg, TRUE);
if (ap->preg != - 1)
putsizedreg("%s+", ap->preg, 4);
putsizedreg("%s", ap->sreg, 4);
if (scale != 1)
oprintf(outputFile, "*%d", scale);
if (ap->offset)
{
oputc('+', outputFile);
putconst(ap->offset);
}
oputc(']', outputFile);
}
break;
default:
DIAG("illegal address mode.");
break;
}
}
//-------------------------------------------------------------------------
void put_code(OCODE *cd)
/*
* outputFile a generic instruction.
*/
{
int op = cd->opcode, len = 0, len2 = 0;
AMODE *aps = cd->oper1, *apd = cd->oper2, *ap3 = cd->oper3;
if (!prm_asmfile)
return ;
if (op == op_line)
{
if (!prm_lines)
return ;
oprintf(outputFile, ";\n; Line %d:\t%s\n;\n", (int)apd, (char*)aps);
return ;
}
else if (op == op_comment)
{
if (!prm_lines)
return ;
oprintf(outputFile, "%s", aps);
return ;
}
else if (op == op_void || op == op_blockstart || op == op_blockend)
return ;
if (aps)
len = aps->length;
if (apd)
len2 = apd->length;
needpointer = (len != len2) || ((!aps || aps->mode != am_dreg) && (!apd ||
apd->mode != am_dreg));
putop(op, aps, apd, cd->noopt);
if (prm_nasm && ((op >= op_ja && op <= op_jns && op != op_jecxz) || op ==
op_jmp && aps->mode == am_immed && !apd))
{
if (cd->branched &BR_SHORT)
oprintf(outputFile, "\tSHORT");
else
oprintf(outputFile, "\tNEAR");
nosize = TRUE;
}
else if (op == op_jmp && aps->mode == am_immed && aps->offset->nodetype ==
en_labcon && (cd->branched &BR_SHORT))
{
oprintf(outputFile, "\tSHORT");
nosize = TRUE;
}
switch (op)
{
case op_rep:
case op_repz:
case op_repe:
case op_repnz:
case op_repne:
case op_lock:
return ;
}
putlen(len);
if (aps != 0)
{
int separator;
oprintf(outputFile, "\t");
if ((op == op_jmp || op == op_call) && aps && apd)
{
separator = ':';
}
else
{
separator = ',';
}
if (op == op_dd)
nosize = TRUE;
putamode(aps);
nosize = FALSE;
if (apd != 0)
{
oputc(separator, outputFile);
putamode(apd);
}
if (ap3 != 0)
{
oputc(separator, outputFile);
putamode(ap3);
}
}
oprintf(outputFile, "\n");
}
//-------------------------------------------------------------------------
void gen_strlab(SYM *sp)
/*
* generate a named label.
*/
{
char buf[512];
putsym(buf, sp, sp->name);
if (prm_asmfile)
if (curseg == dataseg || curseg == bssxseg)
{
newlabel = TRUE;
oprintf(outputFile, "\n%s", buf);
outcol = strlen(buf) + 1;
}
else
oprintf(outputFile, "%s:\n", buf);
}
//-------------------------------------------------------------------------
void put_label(int lab)
/*
* outputFile a compiler generated label.
*/
{
if (prm_asmfile)
oprintf(outputFile, "L_%d:\n", lab);
else
outcode_put_label(lab);
}
//-------------------------------------------------------------------------
void put_staticlabel(long label)
{
if (prm_asmfile)
{
nl();
if (curseg == dataseg || curseg == bssxseg)
{
newlabel = TRUE;
oprintf(outputFile, "\nL_%ld", label);
outcol = 8;
}
else
oprintf(outputFile, "L_%ld:\n", label);
}
else
outcode_put_label(label);
}
//-------------------------------------------------------------------------
void genfloat(long double val)
/*
* Output a float value
*/
{
if (prm_asmfile)
{
if (gentype == floatgen && outcol < 60)
{
oprintf(outputFile, ",%.16e", (double)val);
outcol += 8;
}
else
{
if (!newlabel)
nl();
else
newlabel = FALSE;
oprintf(outputFile, "\tDD\t%.16e", (double)val);
gentype = floatgen;
outcol = 19;
}
}
else
outcode_genfloat(val);
}
//-------------------------------------------------------------------------
void gendouble(long double val)
/*
* Output a double value
*/
{
if (prm_asmfile)
if (gentype == doublegen && outcol < 60)
{
oprintf(outputFile, ",%.16e", (double)val);
outcol += 8;
}
else
{
if (!newlabel)
nl();
else
newlabel = FALSE;
oprintf(outputFile, "\tDQ\t%.16e", (double)val);
gentype = doublegen;
outcol = 19;
}
else
outcode_gendouble(val);
}
//-------------------------------------------------------------------------
void genlongdouble(long double val)
/*
* Output a double value
*/
{
if (prm_asmfile)
if (gentype == longdoublegen && outcol < 60)
{
oprintf(outputFile, ",%.16e", (double)val);
outcol += 8;
}
else
{
if (!newlabel)
nl();
else
newlabel = FALSE;
oprintf(outputFile, "\tDT\t%.16e", (double)val);
gentype = longdoublegen;
outcol = 19;
}
else
outcode_genlongdouble(val);
}
//-------------------------------------------------------------------------
int genstring(char *str, int uselong, int len)
/*
* Generate a string literal
*/
{
if (prm_asmfile)
if (uselong)
{
len /= 2;
while (len--)
{
genword(*((short*)str));
str += 2;
}
return pstrlen(str) *2;
}
else
{
while (len--)
genbyte(*str++);
return strlen(str);
}
else
outcode_genstring(str, len);
}
//-------------------------------------------------------------------------
void genbyte(long val)
/*
* Output a byte value
*/
{
if (prm_asmfile)
if (gentype == bytegen && outcol < 60)
{
oprintf(outputFile, ",0%XH", val &0x00ff);
outcol += 4;
}
else
{
if (!newlabel)
nl();
else
newlabel = FALSE;
oprintf(outputFile, "\tDB\t0%XH", val &0x00ff);
gentype = bytegen;
outcol = 19;
}
else
outcode_genbyte(val);
}
void genbool(int val)
{
genbyte(val);
}
//-------------------------------------------------------------------------
void genword(long val)
/*
* Output a word value
*/
{
if (prm_asmfile)
if (gentype == wordgen && outcol < 58)
{
oprintf(outputFile, ",0%XH", val &0x0ffff);
outcol += 6;
}
else
{
if (!newlabel)
nl();
else
newlabel = FALSE;
oprintf(outputFile, "\tDW\t0%XH", val &0x0ffff);
gentype = wordgen;
outcol = 21;
}
else
outcode_genword(val);
}
//-------------------------------------------------------------------------
void genlong(long val)
/*
* Output a long value
*/
{
if (prm_asmfile)
if (gentype == longgen && outcol < 56)
{
oprintf(outputFile, ",0%lXH", val);
outcol += 10;
}
else
{
if (!newlabel)
nl();
else
newlabel = FALSE;
oprintf(outputFile, "\tDD\t0%lXH", val);
gentype = longgen;
outcol = 25;
}
else
outcode_genlong(val);
}
void genint(val)
{
genlong(val);
}
void genenum(val)
{
genlong(val);
}
//-------------------------------------------------------------------------
void genlonglong(LLONG_TYPE val)
/*
* Output a long value
*/
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -