📄 masmber_c0.cpp
字号:
//---------------------------------------------------------------------------
//-------- MAsmber_C0.cpp ---------------------------------------------------
//---------------------------------------------------------------------------
#include "JsGlobal_H.h"
#include "MAsmber_H.h"
#include "AsmF_H.h"
#include "OBJfile_H.h"
#include "LISTfile_H.h"
#include "LabelManiger_H.h"
#include "InstSystem_H.h"
#include "OBJModule_H.h"
#include "MacroManager_H.h"
//---------------------------------------------------------------------------
//------ 构造器 -------------------------------------------------------------
MacroAsmber::MacroAsmber(int argc, char** argv)
:Margc(argc),
Margv(argv),
NestGroup(0), // 各嵌套计数器清零。
FlagGroup(0x0F), // 标志群
ConflictBn(0), // 冲突检测开关组
AsmFn(NULL), // 当前汇编文件指针
Ln(NULL), // 当前汇编行指针
SegPt(NULL), // 当前段指针
JModulePt(NULL), // 当前模块指针
objFilePt(NULL), // 当前目标文件指针
LstFilePt(NULL) // 当前列表文件指针
{ // .....................................................................
Instm = new InstSystem; // 指令系统
LabMger = new LabelManager(*this); // 标号管理器
MacroMger = new MacrosManager(*this); // 创建一个宏管理器。
MvList = new MacroVarList; // 条件控制变量管理器。
} // end constructor
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
SpecialRegs MacroAsmber::SRegAddr[] =
{ // name type addr value
{ "P0", LB_DATA, 0x80 },
{ "SP", LB_DATA, 0x81 },
{ "DPL", LB_DATA, 0x82 },
{ "DPH", LB_DATA, 0x83 },
{ "PCON", LB_DATA, 0x87 },
{ "TCON", LB_DATA, 0x88 },
{ "TMOD", LB_DATA, 0x89 },
{ "TL0", LB_DATA, 0x8a },
{ "TL1", LB_DATA, 0x8b },
{ "TH0", LB_DATA, 0x8c },
{ "TH1", LB_DATA, 0x8d },
{ "P1", LB_DATA, 0x90 },
{ "SCON", LB_DATA, 0x98 },
{ "SBUF", LB_DATA, 0x99 },
{ "P2", LB_DATA, 0xa0 },
{ "IE", LB_DATA, 0xa8 },
{ "P3", LB_DATA, 0xb0 },
{ "IP", LB_DATA, 0xb8 },
{ "PSW", LB_DATA, 0xd0 },
{ "ACC", LB_DATA, 0xe0 },
{ "B", LB_DATA, 0xf0 },
{ "IT0", LB_BIT, 0x88 },
{ "IE0", LB_BIT, 0x89 },
{ "IT1", LB_BIT, 0x8a },
{ "IE1", LB_BIT, 0x8b },
{ "TR0", LB_BIT, 0x8c },
{ "TF0", LB_BIT, 0x8d },
{ "TR1", LB_BIT, 0x8e },
{ "TF1", LB_BIT, 0x8f },
{ "RI", LB_BIT, 0x98 },
{ "TI", LB_BIT, 0x99 },
{ "RB8", LB_BIT, 0x9a },
{ "TB8", LB_BIT, 0x9b },
{ "DEM", LB_BIT, 0x9c },
{ "SM2", LB_BIT, 0x9d },
{ "SM1", LB_BIT, 0x9e },
{ "SM0", LB_BIT, 0x9f },
{ "EX0", LB_BIT, 0xa8 },
{ "ET0", LB_BIT, 0xa9 },
{ "EX1", LB_BIT, 0xaa },
{ "ET1", LB_BIT, 0xab },
{ "ES", LB_BIT, 0xac },
{ "EA", LB_BIT, 0xaf },
{ "TX0", LB_BIT, 0xb8 },
{ "PT0", LB_BIT, 0xb9 },
{ "PK1", LB_BIT, 0xba },
{ "PT1", LB_BIT, 0xbb },
{ "PS", LB_BIT, 0xbc },
{ "P", LB_BIT, 0xd0 },
{ "F1", LB_BIT, 0xd1 },
{ "OV", LB_BIT, 0xd2 },
{ "RS0", LB_BIT, 0xd3 },
{ "RS1", LB_BIT, 0xd4 },
{ "F0", LB_BIT, 0xd5 },
{ "AC", LB_BIT, 0xd6 },
{ "CY", LB_BIT, 0xd7 },
{ "AR0", LB_DATA, 0x00 },
{ "AR1", LB_DATA, 0x01 },
{ "AR2", LB_DATA, 0x02 },
{ "AR3", LB_DATA, 0x03 },
{ "AR4", LB_DATA, 0x04 },
{ "AR5", LB_DATA, 0x05 },
{ "AR6", LB_DATA, 0x06 },
{ "AR7", LB_DATA, 0x07 },
{ "", NULL, 0x00 }
};
// end SpecialRegs SRegAddr[]
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 把命令行参数转化为汇编行,执行后,再丢掉。
//---------------------------------------------------------------------------
ERR MacroAsmber::CommandLineToAsmL()
{ if(Margc <= 2) { return OK_no_Err; } // endif
Jstring CmArgStr("$ ");
for(register int8u i = 2; i < Margc; ++i)
{ CmArgStr = CmArgStr + Margv[i] + " "; } // end for
Ln = new AsmLine; // 创建新汇编行对象
// 把ASCII文本字串转换成汇编行。
char ss[256];
Jassert(CmArgStr.getLen()<255);
ERR err = StrLexToAsmline(CmArgStr.makeStr(ss), Ln, AsmFn->CommentEnable ); // 带回err值。
if(!err) { err = MajorCtrlParse(Ln); } // endif
// 首要控制指令
if(!err) { delete Ln; Ln = NULL; return OK_no_Err; } // endif
// Have Error! 出错信息放在0行。
AsmFn->AddAsmLine(Ln); return Have_Errs;
} // end CommandLineToAsmL
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// pt指向EXTRNKn。要求pt->next是WordList。
// 外部变量标号的Value值存有该外部标号的ExtID.
//---------------------------------------------------------------------------
ERR MacroAsmber::AddExtLabelThenDel(Tokenfield* pt)
{ ERR erra = OK_no_Err;
int8u LBtyp = (int8u)pt->Token2; // 获取外部变量的类型。
pt = pt->next; // Now, pt->Token == WordList, 使pt指向参数表。
// 原型 JlabelNode* AddLabel( ERR &err,const Jstring &name,int8u labelTp,
// bool var, AsmLine* Crln, Tokenfield* pt,
// ASM_Segment* rSeg = NULL,
// bool Ind = false, bool Ext = false )
for( ; pt->ExpPt; TokenOper::DelTokenNode(pt->ExpPt) )
{ ERR err;
JLabelNode* tp =
LabMger->AddLabel( err, // 错误返回码。
pt->ExpPt->Name, // 外部变量名。
LBtyp, // 标号类型(由Token的性质决定)。
false, // 标号是变量!
Ln, // 创建该标号的汇编行的指针。
NULL, // 表达式(无)。
NULL, // 所属段(不属于任何段)。
false, // 不应间接访问。
true ); // 外部变量标志!
if(err) { erra = Have_Errs; } // endif break from "for" loop
else // 成功添加一个外部标号。
{ tp->SetValue(0); // 外部标号的Value是0!! ValueOK!
register int16u symid = JModulePt->AddExtSymDef(tp);
tp->SetExtID(symid); // 外部变量标号的Value值存有该外部标号的ExtID.
} // end else
} // end for
return erra;
} // end AddExtLabelThenDel
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#define ErrInORGdataCal 1
#define ErrIndataLess 2
#define ErrInIllType 3
#define ErrInIllSeg 4
//---------------------------------------------------------------------------
// 遇到ORG指令的动作。ORG并不改变当前段。
// ORG指令不能计算前向参考式。必须不能,可由理论证明。
// This work is done in Pass1&2.
//---------------------------------------------------------------------------
ERR MacroAsmber::TknIsORGDo(Tokenfield* pt)
{ ERR err;
const TriVal* t = LabMger->CalExpression(err, pt->next->ExpPt); // 带err返回。
if(err)
{ if(err != LabNotReady)
{ OutputErr(ORGdataCalErr); return ErrInORGdataCal; } // endif
else // err == LabNotReady
{ SegPt->SegLc = (int16u)(t->val); // 重新设置段计数器(捉摸值), 不产生新段
Ln->lc = SegPt->SegLc; // 汇编行更新地址偏移(捉摸值)
return OK_no_Err;
} // end else
} // endif
// no error.
if( t->typ > LB_NUM ) // (LB_NUM==5)
{ OutputErr(ExpTypNotMatchErr); return ErrInIllType; } // endif
if( t->rseg && t->rseg != SegPt )
{ OutputErr(SegNotMatchErr); return ErrInIllSeg; } // endif
if(not16bit(t->val))
{ OutWarning(DataBeTrun16Warn); } // endif
if(t->val < SegPt->SegBase) // 如果ORG地址 < 当前段的基地址
{ OutputErr(ORGdataLessErr); return ErrIndataLess; } // endif
SegPt->SegLc = (int16u)(t->val); // 重新设置段计数器, 不产生新段
Ln->lc = SegPt->SegLc; // 汇编行更新地址偏移
pt->Value = SegPt->SegLc; // Token的val值保存偏移量
if(Pass_2)
{ SegPt->UpdateSegSize();
SegPt->CloseAndAddSegTrp(Ln);
Ln->Enable = false;
} // endif
return OK_no_Err;
} // end TknIsORGDo
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 将DB升级,Val值将会改为指向新JdatBlock的指针。
// 计算该DB语句占用的字节数。设置汇编行占用字节数长度,段计数器增加。
// This work is done in Pass1.
//---------------------------------------------------------------------------
void MacroAsmber::TknIsDBDoSth(Tokenfield* pt)
{ pt->Token = pt->Token2; // Token升级
register int16u count = 0;
do // 计算DB块长度
{ pt = pt->next;
switch(pt->Token)
{ case ExpresnKn : { count++; break; } // end case
case LongCharn : case StrDataKn :
{ count += pt->DatPt->GetLen(); break; } // end case
default: { EThrows(printf("\nTknIsDBDoSth out of run!"); Waitkey;) }
} // end switch
} while(pt->next);
Ln->len = count; // 设置汇编行占用字节数长度
SegPt->SegLc += count; // 段计数器增加
} // end TknIsDBDo
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 将DW升级,Val值将会改为指向新JdatBlock的指针。
// 计算该DW语句占用的字节数。设置汇编行占用字节数长度,段计数器增加。
// This work is done in Pass1.
//---------------------------------------------------------------------------
void MacroAsmber::TknIsDWDoSth(Tokenfield* pt)
{ pt->Token = pt->Token2; // Token升级
register int16u count = 0;
do // 计算DW块长度
{ pt = pt->next;
switch(pt->Token)
{ case ExpresnKn :
case LongCharn :
case StrDataKn : count += 2; break;
EThrows(default: printf("\nTknIsDWDoSth out of run!"); Waitkey;)
} // end switch
} while(pt->next);
Ln->len = count; // 设置汇编行占用字节数长度
SegPt->SegLc += count; // 段计数器增加
} // end TknIsDWDoSth
//---------------------------------------------------------------------------
#define ErrInDSExp 1
#define ErrInDSTyp 2
#define ErrInDSSeg 3
//---------------------------------------------------------------------------
// DS指令不能计算前向参考式。
// 计算该DS语句占用的字节数。设置汇编行占用字节数长度,段计数器增加。
// This work is done in Pass1&2.
//---------------------------------------------------------------------------
ERR MacroAsmber::TknIsDSDoSth(Tokenfield* pt)
{ ERR err;
const TriVal* t = LabMger->CalExpression(err, pt->next->ExpPt);
if(err)
{ if(err != LabNotReady)
{ OutputErr(ExpSyrErr); return ErrInDSExp; } // endif
} // endif
if( t->rseg || t->typ != LB_NUM || t->rel !='A' )
{ OutputErr(ExpTypNotMatchErr); return ErrInDSTyp; } // endif
if(SegPt->GetSegType() == SEG_BIT ) // !!!!!
{ OutputErr(SegNotMatchErr); return ErrInDSSeg; } // endif
if(not16bit(t->val))
{ OutWarning(DataBeTrun16Warn); }
pt->Token2 = (int16u)(t->val); // pt->Value = DS数值
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -