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

📄 inasm386.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 4 页
字号:
/* 
Copyright 1994-2003 Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  

This program is derived from the cc68k complier by 
Matthew Brandt (mattb@walkingdog.net) 

You may contact the author of this derivative at:

mailto::camille@bluegrass.net

or by snail mail at:

David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
 */
/*
 * inline assembler (386)
 */
#include <stdio.h> 
#include <string.h>
#include "lists.h"
#include "expr.h" 
#include "c.h" 
#include "ccerr.h"
#include "gen386.h"

extern long lc_maxauto;

extern int asmline;
extern int lastch;
extern enum e_sym lastst;
extern LLONG_TYPE ival;
extern short *lptr;
extern TABLE lsyms;
extern int nextlabel;
extern char lastid[];
extern int prm_asmopt;
extern int prm_nasm, prm_asmfile;

ASMNAME *keyimage;
ASMREG *regimage;
static SYM *lastsym;
static enum e_op op;

ASMREG reglst[] = 
{
    {
        "cs", am_seg, 1, 2
    } , 
    {
        "ds", am_seg, 2, 2
    }
    , 
    {
        "es", am_seg, 3, 2
    }
    , 
    {
        "fs", am_seg, 4, 2
    }
    , 
    {
        "gs", am_seg, 5, 2
    }
    , 
    {
        "ss", am_seg, 6, 2
    }
    , 
    {
        "al", am_dreg, 0, 1
    }
    , 
    {
        "cl", am_dreg, 1, 1
    }
    , 
    {
        "dl", am_dreg, 2, 1
    }
    , 
    {
        "bl", am_dreg, 3, 1
    }
    , 
    {
        "ah", am_dreg, 4, 1
    }
    , 
    {
        "ch", am_dreg, 5, 1
    }
    , 
    {
        "dh", am_dreg, 6, 1
    }
    , 
    {
        "bh", am_dreg, 7, 1
    }
    , 
    {
        "ax", am_dreg, 0, 2
    }
    , 
    {
        "cx", am_dreg, 1, 2
    }
    , 
    {
        "dx", am_dreg, 2, 2
    }
    , 
    {
        "bx", am_dreg, 3, 2
    }
    , 
    {
        "sp", am_dreg, 4, 2
    }
    , 
    {
        "bp", am_dreg, 5, 2
    }
    , 
    {
        "si", am_dreg, 6, 2
    }
    , 
    {
        "di", am_dreg, 7, 2
    }
    , 
    {
        "eax", am_dreg, 0, 4
    }
    , 
    {
        "ecx", am_dreg, 1, 4
    }
    , 
    {
        "edx", am_dreg, 2, 4
    }
    , 
    {
        "ebx", am_dreg, 3, 4
    }
    , 
    {
        "esp", am_dreg, 4, 4
    }
    , 
    {
        "ebp", am_dreg, 5, 4
    }
    , 
    {
        "esi", am_dreg, 6, 4
    }
    , 
    {
        "edi", am_dreg, 7, 4
    }
    , 
    {
        "st", am_freg, 0, 10
    }
    , 
    {
        "cr0", am_screg, 0, 4
    }
    , 
    {
        "cr1", am_screg, 1, 4
    }
    , 
    {
        "cr2", am_screg, 2, 4
    }
    , 
    {
        "cr3", am_screg, 3, 4
    }
    , 
    {
        "cr4", am_screg, 4, 4
    }
    , 
    {
        "cr5", am_screg, 5, 4
    }
    , 
    {
        "cr6", am_screg, 6, 4
    }
    , 
    {
        "cr7", am_screg, 7, 4
    }
    , 
    {
        "dr0", am_sdreg, 0, 4
    }
    , 
    {
        "dr1", am_sdreg, 1, 4
    }
    , 
    {
        "dr2", am_sdreg, 2, 4
    }
    , 
    {
        "dr3", am_sdreg, 3, 4
    }
    , 
    {
        "dr4", am_sdreg, 4, 4
    }
    , 
    {
        "dr5", am_sdreg, 5, 4
    }
    , 
    {
        "dr6", am_sdreg, 6, 4
    }
    , 
    {
        "dr7", am_sdreg, 7, 4
    }
    , 
    {
        "tr0", am_streg, 0, 4
    }
    , 
    {
        "tr1", am_streg, 1, 4
    }
    , 
    {
        "tr2", am_streg, 2, 4
    }
    , 
    {
        "tr3", am_streg, 3, 4
    }
    , 
    {
        "tr4", am_streg, 4, 4
    }
    , 
    {
        "tr5", am_streg, 5, 4
    }
    , 
    {
        "tr6", am_streg, 6, 4
    }
    , 
    {
        "tr7", am_streg, 7, 4
    }
    , 
    {
        "st", am_freg, 0, 4
    }
    , 
    {
        "byte", am_ext, akw_byte, 0
    }
    , 
    {
        "word", am_ext, akw_word, 0
    }
    , 
    {
        "dword", am_ext, akw_dword, 0
    }
    , 
    {
        "fword", am_ext, akw_fword, 0
    }
    , 
    {
        "qword", am_ext, akw_qword, 0
    }
    , 
    {
        "tbyte", am_ext, akw_tbyte, 0
    }
    , 
    {
        "ptr", am_ext, akw_ptr, 0
    }
    , 
    {
        "offset", am_ext, akw_offset, 0
    }
    , 
    {
        0, 0, 0
    }
    , 
};

static int floating;

void inasmini(void){}
static void asm_err(int errnum)
{
    *lptr = 0;
    lastch = ' ';
    generror(errnum, 0, 0);
    getsym();
}

//-------------------------------------------------------------------------

static ENODE *asm_ident(void)
{
    ENODE *node = 0;
    char *nm;
    int fn = FALSE;
    if (lastst != id)
        asm_err(ERR_IDEXPECT);
    else
    {
        SYM *sp;
        ENODE *qnode = 0;
        nm = litlate(lastid);
        getsym();
        /* No such identifier */
        /* label, put it in the symbol table */
        if ((sp = gsearch(nm)) == 0)
        {
            sp = makesym(sc_ulabel);
            sp->name = nm;
            sp->tp = xalloc(sizeof(TYP));
            sp->tp->type = bt_unsigned;
            sp->tp->uflags = UF_USED;
            sp->tp->bits = sp->tp->startbit =  - 1;
            sp->value.i = nextlabel++;
            insert(sp, &lsyms);
            node = xalloc(sizeof(ENODE));
            node->nodetype = en_labcon;
            node->v.i = sp->value.i;
        }
        else
        {
            /* If we get here the symbol was already in the table
             */
            foundsp: sp->tp->uflags |= UF_USED;
            switch (sp->storage_class)
            {
                case sc_static:
                case sc_global:
                case sc_external:
                case sc_externalfunc:
                case sc_abs:
                    sp->mainsym->extflag = TRUE;
                        if (sp->value.classdata.gdeclare)
                            sp->value.classdata.gdeclare->mainsym->extflag =
                                TRUE;
                    if (sp->tp->type == bt_func || sp->tp->type == bt_ifunc)
                    {
                        /* make a function node */
                        node = makenode(en_napccon, sp, 0);
                        isfunc: if (sp->tp->type != bt_func && sp->tp->type !=
                            bt_ifunc)
                            generror(ERR_MISMATCH, 0, 0);
                    }
                    else
                    /* otherwise make a node for a regular variable */
                        if (sp->absflag)
                            node = makenode(en_absacon, sp, 0);
                        else
                    if (sp->tp->type == bt_func || sp->tp->type == bt_ifunc)
                    {
                        fn = TRUE;
                        node = makenode(en_napccon, sp, 0);
                    }
                        else
                            if (sp->staticlabel)
                                node = makenode(en_nalabcon, sp, 0);
                            else
                                node = makenode(en_nacon, sp, 0);
                    break;
                case sc_const:
                    /* constants and enums */
                    node = makeintnode(en_icon, sp->value.i);
                    break;
                case sc_label:
                case sc_ulabel:
                    node = xalloc(sizeof(ENODE));
                    node->nodetype = en_labcon;
                    node->v.i = sp->value.i;
                    break;
                default:
                     /* auto and any errors */
                    if (sp->storage_class != sc_auto && sp->storage_class !=
                        sc_autoreg)
                    {
                        gensymerror(ERR_ILLCLASS2, sp->name);
                    }
                    else
                    {
                        /* auto variables */
                        if (sp->storage_class == sc_auto)
                            node = makenode(en_autocon, sp, 0);
                        else if (sp->storage_class == sc_autoreg)
                            node = makenode(en_autoreg, sp, 0);
                        if (fn)
                            goto isfunc;
                    }
                    break;
            }

            (node)->cflags = 0;
        }
        lastsym = sp;
    }
    return node;
}

//-------------------------------------------------------------------------

static ENODE *asm_label(void)
{
    char *nm = litlate(lastid);
    ENODE *node;
    SYM *sp;
    getsym();
    /* No such identifier */
    /* label, put it in the symbol table */
    if ((sp = search(lastid, &lsyms)) == 0)
    {
        sp = makesym(sc_label);
        sp->name = litlate(lastid);
        sp->tp = xalloc(sizeof(TYP));
        sp->tp->type = bt_unsigned;
        sp->tp->uflags = 0;
        sp->tp->bits = sp->tp->startbit =  - 1;
        sp->value.i = nextlabel++;
        insert(sp, &lsyms);
    }
    else
    {
        if (sp->storage_class == sc_label)
        {
            *lptr = 0;
            lastch = ' ';
            gensymerror(ERR_DUPLABEL, sp->name);
            getsym();
            return 0;
        }
        if (sp->storage_class != sc_ulabel)
        {
            asm_err(ERR_ALABEXPECT);
            return 0;
        }
        sp->storage_class = sc_label;
    }
    if (lastst != colon)
    {
        asm_err(ERR_ALABEXPECT);
        return 0;
    }
    getsym();
    node = xalloc(sizeof(ENODE));
    node->nodetype = en_labcon;
    node->v.i = sp->value.i;
    return node;
}

//-------------------------------------------------------------------------

static int asm_getsize(void)
{
    int sz = 0;
    switch (regimage->regnum)
    {
        case akw_byte:
            sz = 1;
            break;
        case akw_word:
            sz = 2;
            break;
        case akw_dword:
            sz = floating ? 7 : 4;
            break;
        case akw_fword:
            sz = 7;
            break;
        case akw_qword:
            sz = 8;
            break;
        case akw_tbyte:
            sz = 10;
            break;
        case akw_offset:
            sz = 4;
            break;
    };
    getsym();
    if (lastst == kw_asmreg)
    {
        regimage = keyimage;
        if (regimage->regtype == am_ext)
        {
            if (regimage->regnum != akw_ptr)
            {
                asm_err(ERR_AILLADDRESS);
                return 0;
            }
            getsym();
        }
    }
    if (lastst != kw_asmreg && lastst != openbr && lastst != id)
    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -