📄 inasm386.c
字号:
/*
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 + -