⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 outas386.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 *      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 + -