📄 masmber_c4.cpp
字号:
//---------------------------------------------------------------------------
// MAsmber_C4.cpp
//---------------------------------------------------------------------------
#include "MAsmber_H.h"
#include "AsmF_H.h"
#include "OBJfile_H.h"
#include "ListFile_H.h"
#include "OBJModule_H.h"
#include "TokenOper_H.h"
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//
// 目标代码生成器
//
//---------------------------------------------------------------------------
#define DebugKit(str) //DebugMsg(str)
//---------------------------------------------------------------------------
// 汇编行代码生成。
// 要对Ln所指向的汇编行进行分析。
// 如果有错,则返回非零值。
//---------------------------------------------------------------------------
ERR MacroAsmber::LineToObjCode()
{ if(!Ln->Enable) { return 0; } // 如果此行被禁用,忽略此行
DebugKit(printf("\nToObjCode Ln=%d",Ln->LineNo); Debugkey);
int16u temp = Ln->lc; // 暂存Ln->lc,以便以后恢复
Tokenfield* pt = Ln->FirstTkn(); // 每次从行头开始
ERR err = OK_no_Err;
switch(pt->Token)
{ case KnownInst : // 这一次, 必须把所有的表达式都算出来!!!
{ Ln->len = pt->Opset->len; // 给汇编行长度赋值。
err = Translate(pt); // 从 KnownInst -> Instcode 的转换
break;
} // end case
case DB :
{ err = DBToDBObj(pt); // 成功=0,否则返回出错码
break;
} // end case
case DW :
{ err = DWToDWObj(pt); // 成功=0,否则返回出错码
break;
} // end case
case SETsDefken:
{ JLabelNode* temp;
if( LabMger->SearchLinkList(pt->Name, temp) ) // temp 带回搜索值
{ temp->CopyFrom(*pt->LabPt); } // endif
else
{ DebugKit(printf("\nBugs in LineToObjCode!"); Debugkey;); // debug
} // end else
Ln->Enable = false;
break;
} // end case
case USINGTkn : { err = TknIsUsing_Do(pt); Ln->Enable = false;
if(err) { return Have_Errs; }
break;
} // end case
default: { err = Have_Errs;
EThrows(printf("\nToObjCode out of run!\n"); Debugkey;); // debug
} // end default
} // end switch
Ln->lc = temp; // 恢复Ln->lc
return err;
} // end LineToObjCode
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 目标代码生成。
//---------------------------------------------------------------------------
ERR MacroAsmber::FileToObjCode()
{ ERR erra = OK_no_Err;
for( Ln = AsmFn->FirstLine(); Ln; Ln = Ln->next ) // 全文件扫描
{
if( LineToObjCode() ) { erra = Have_Errs; } // endif
} // end for
return erra;
} // end ToObjCode
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#define IDType(typ) (((typ)==LB_SEG) ? IDBLK_SEG_OPND : IDBLK_REL_OPND)
//---------------------------------------------------------------------------
// 从DB 到 DBObjCode 的进化!
// pt->Token == DB
// DB ->next must not be NULL
// err = 0, 成功; err = 1, 错误。
//---------------------------------------------------------------------------
ERR MacroAsmber::DBToDBObj(Tokenfield* pt) // 成功=0,否则返回出错码
{ ERR err = OK_no_Err;
int16u lctemp = Ln->lc; // 暂存
for(Tokenfield* tt = pt->next; tt; tt = tt->next)
{ switch(tt->Token)
{ case LongCharn : case StrDataKn : // 常量字符串
{ Ln->lc += tt->DatPt->GetLen(); // 原Token保持不变。
break;
} // end case
case ExpresnKn :
{ const TriVal& trv = *LabMger->CalExpression(err, tt->ExpPt); // 带回err。
if(err) { return Have_Errs; } // 该行异常终止
if(not8bit(trv.val)) { OutWarning(DataBeTrun8Warn); } // endif
TokenOper::DelTokenList(tt->ExpPt); // 释放内存
tt->Token = ObjcodeKn; // Token进化
tt->D4ary = new Dat4ary; // 一个Byte就有一个D4ary.
Dat4ary &Ndary = *(tt->D4ary);
if( Ndary.ByteSettle(trv, Ln->lc) )
{ DebugKit(printf("\nErr in ByteSettle.\n"); Debugkey;); // debug
return Have_Errs;
} // endif
++Ln->lc; break;
} // end case
default:
{ EThrows(printf("\nDBToDBObj out of run!"); Debugkey;); // debug
} // default
} // end switch
} // end for
Ln->lc = lctemp; // 恢复
pt->Token = DBObjCode; // Token的进化!
return OK_no_Err;
} // end DBToDBObj
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 从DW 到 DWObjCode 的进化!
// pt->Token == DW
// DW ->next must not be NULL
// err = 0, 成功; err = 1, 错误。
//---------------------------------------------------------------------------
ERR MacroAsmber::DWToDWObj(Tokenfield* pt) // 成功=0,否则返回出错码
{ ERR err = OK_no_Err;
int16u lctemp = Ln->lc; // 暂存
for(Tokenfield* tt = pt->next; tt; tt = tt->next)
{ switch(tt->Token)
{ case LongCharn : case StrDataKn :
{ Dat4ary &Ndary = *new Dat4ary;
Ndary.dat[3] = 2; // len = 2
if(tt->DatPt->GetLen() > 2)
{ OutWarning(DataBeTrun16Warn); } // endif
if(tt->DatPt->GetLen() < 2)
{ OutWarning(DataBeExtentWarn);
register const int8u* w = (const char*)*(tt->DatPt);
Ndary.dat[0] = 0; // high byte extended to 0.
Ndary.dat[1] = *w;
} // endif
else //(==2)
{ register const int8u* w = (const char*)*(tt->DatPt);
Ndary.dat[0] = *w;
Ndary.dat[1] = *(w+1);
} // end else
delete tt->DatPt; // 释放内存
tt->Token = ObjcodeKn; // Token进化
tt->D4ary = &Ndary;
Ln->lc += 2; break;
} // end case
case ExpresnKn :
{ const TriVal& trv = *LabMger->CalExpression(err, tt->ExpPt); // 带回err。
if(err) { return Have_Errs; } // 该行异常终止
if(not16bit(trv.val)) { OutWarning(DataBeTrun16Warn); } // endif
TokenOper::DelTokenList(tt->ExpPt); // 释放内存
tt->Token = ObjcodeKn; // Token进化
tt->D4ary = new Dat4ary;
Dat4ary &Ndary = *(tt->D4ary);
if( Ndary.WordSettle(trv, Ln->lc) )
{ DebugKit(printf("\nErr in WordSettle.\n"); Debugkey;); // debug
return Have_Errs;
} // endif
Ln->lc += 2; break;
} // end case
default: { EThrows(printf("\nDWToDWObj out of run!\n"); Debugkey;); // debug
} // end default
} // end switch
} // end for
Ln->lc = lctemp; // 恢复
pt->Token = DWObjCode; // Token的进化!
return OK_no_Err;
} // end DWToDWObj
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// 把汇编指令翻译成目标代码。
// pt是指向KnownInst的指针, pt->Opset指向该指令的OPset。
// err = 1, 第一个操作数出错。
// err = 2, 第二个操作数出错。
// err = 3, 第三个操作数出错。
//---------------------------------------------------------------------------
ERR MacroAsmber::Translate(Tokenfield* pt) // 成功=0,否则返回出错码
{ ERR err = 0;
// At first, pt->Token == KnownInst.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -