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

📄 objmodule_c.cpp

📁 单片机宏汇编器的源程序。给一些爱好者作为学习编译原理和 C 程序设计的例子.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//---------------------------------------------------------------------------
//-------- OBJModule_C.cpp ---------------------------------------------------
//---------------------------------------------------------------------------

#include "OBJModule_H.h"
#include "LabelManiger_H.h"
#include "MAsmber_H.h"
#include "ASM_Segment_H.h"
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
//
//                    OBJ模块生成器
//
//---------------------------------------------------------------------------
#define DebugKit(str)    //DebugMsg(str)

//------ 构造器 -------------------------------------------------------------
OBJmodule::OBJmodule(MacroAsmber& m, const Jstring& Mname)
                            : masm(m),
                              TRN_ID(0xFD),REG_MSK(0x01),
                              ExtSymDefHead(NULL),ExtSymSum(0),
                              Debug(false)
{ ModuleName = Mname;     // 模块名,默认为不带扩展名的文件名
  ModuleName.ToUp();      // 转成大写。
   SrcfilePt = masm.AsmFn;  // 源程序文件指针
   OBJfilePt = masm.objFilePt; // 目标程序文件指针

  // 创建默认的绝对段,段ID为零。
  SegDefTail = SegDefHead = new ASM_Segment(SEG_CODE);
  SegDefTail = SegDefTail->next = new ASM_Segment(SEG_DATA);
  SegDefTail = SegDefTail->next = new ASM_Segment(SEG_XDATA);
  SegDefTail = SegDefTail->next = new ASM_Segment(SEG_IDATA);
  SegDefTail = SegDefTail->next = new ASM_Segment(SEG_BIT);

} // end constructor
//---------------------------------------------------------------------------

//------ 析构器 -------------------------------------------------------------
OBJmodule::~OBJmodule()
{ for( register ASM_Segment* p; SegDefHead;
       p = SegDefHead->next, delete SegDefHead, SegDefHead = p ); // endfor
} // end destructor
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// 往目标模块添加一个新段。
//---------------------------------------------------------------------------
ASM_Segment* OBJmodule::AddSegment(Tokenfield &tkn)
{ SegDefTail->next = new ASM_Segment;

  ASM_Segment& NewSeg = *(SegDefTail->next);
  NewSeg.SegID    = SegDefTail->SegID + 1;
  NewSeg.SegType  = tkn.Token2;
  NewSeg.RelType  = tkn.loc[1];
  NewSeg.Name     = tkn.Name;
  SegDefTail = SegDefTail->next; // 往链尾添加。
  return SegDefTail;
} // end AddSegment
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// 图示:
//struct ExtSymDef
//{  int8u IDBLK;
//  int16u ExtID;
//  JLabelNode* LabPt;
//   ExtSymDef* next;
//}; // end ExtSymDef
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// 返回SymID。
//---------------------------------------------------------------------------
int16u OBJmodule::AddExtSymDef(JLabelNode* LBpt)
{ ExtSymDef* extSym = new ExtSymDef;

  extSym->IDBLK = IDBLK_EXT_OPND;       // (0x02)
  extSym->LabPt = LBpt;
  extSym->ExtID = ExtSymSum++;          // 分配ExtID。
  extSym->next  = NULL;

  if(ExtSymDefHead)
   { register ExtSymDef* t = ExtSymDefHead;   // find tail
     for( ; t->next; t = t->next ); // end for
     t->next = extSym;                // 从尾部插入
   } // endif
  else
   { ExtSymDefHead = extSym; }        // 从尾部插入

  return extSym->ExtID;
} // end AddExtSymDef
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
void OBJmodule::WriteModuleHeader() // 写一个模块头到文件
{ OBJrecord MHR(0x02);  // Module Header Record
  MHR.AddJstr(ModuleName);
  MHR.AddByte(TRN_ID);
  MHR.AddByte(0x00);    // unused byte
  OBJfilePt->WriteARecord(MHR);
} // end WriteModuleHeader
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
void OBJmodule::WriteModuleENDrec() // 写一个模块尾到文件
{ OBJrecord MER(0x04);  // Module END Record
  MER.AddJstr(ModuleName);
  MER.AddWord(0x0000);  // unused 2 bytes
  MER.AddByte(REG_MSK);
  MER.AddByte(0x00);    // unused byte
  OBJfilePt->WriteARecord(MER);
} // end WriteModuleENDrec
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
void OBJmodule::WriteScopeDefMB() // 写一个模块ScopeDef到文件(Module Block)
{ OBJrecord SDR(0x10);     // Scope Definition Record
  SDR.AddByte(0x00);       // BLK TYP = module block
  SDR.AddJstr(ModuleName); // Block Name
  OBJfilePt->WriteARecord(SDR);
} // end WriteScopeDefrec
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
void OBJmodule::WriteSRCNamesRec()
{ OBJrecord SNR(0x24);      // Source Name Record
  SNR.AddByte(0x00);
  SNR.AddWord(0x0000);      // unused 3 bytes
  SNR.AddJstr(SrcfilePt->FileName); // Source file name
  OBJfilePt->WriteARecord(SNR);
} // end WriteSRCNamesRec
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
void OBJmodule::WriteScopeDefME() // 写一个模块ScopeDef到文件(Module End)
{ OBJrecord SDR(0x10);     // Scope Definition Record
  SDR.AddByte(0x03);       // BLK TYP = module END
  SDR.AddJstr(ModuleName); // Block Name
  OBJfilePt->WriteARecord(SDR);
} // end WriteScopeDefME
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// 把模块中的一系列段的段定义写到文件中。
//---------------------------------------------------------------------------
void OBJmodule::WriteSegDefRecords()
{ for(ASM_Segment* p = SegDefHead;  p;  p = p->next)
   { WriteASegDefRec(p); } // end for
} // end WriteSegDefRecords
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// 产生一个Debug的符号记录组。
//---------------------------------------------------------------------------
inline void OBJmodule::GenDebugSymbolRecs()
{ WriteDebugSegSymRec();   // Debug Segment Symbol
  WriteDebugPubSymRec();   // Debug Public Symbol
  WriteDebugLocalSymRec(); // Debug Local Symbol
} // end GenDebugSymbolRecs
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// 写一个模块到文件。
//---------------------------------------------------------------------------
void OBJmodule::WriteModuleToOBJFile()
{ WriteModuleHeader();     // 写一个模块头记录。

  WriteSegDefRecords();    // 写段定义记录。
  WriteAnExtDefRec();      // 写一个外部变量定义记录。
  WriteAPubDefRec();       // 写一个公共变量定义记录。

  WriteScopeDefMB();       // Scope Begin
  WriteSRCNamesRec();      // Source file name

  GenDebugSymbolRecs();    // 产生Debug的符号记录组。
  GenContentFixLineNo();   //

  WriteScopeDefME();       // Scope Begin
  WriteModuleENDrec();     // 写一个模块尾记录。
} // end WriteModuleToOBJFile
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// 写一个段定义记录。[0FH] Segment Definition Record
// 如果是一个空段,不写入。
// 至少包括一个段。
//---------------------------------------------------------------------------
void OBJmodule::WriteASegDefRec(ASM_Segment* segpt)
{ if(segpt->IsEmpty()) { return; }
  OBJrecord rec(0x0f); // [0FH] Segment Definition Record

  rec.AddWord(segpt->SegID);
  rec.AddByte(segpt->SegInfo());
  rec.AddByte(segpt->RelType);
  rec.AddByte(0x00);      // unused
  rec.AddWord(segpt->SegBase);
  rec.AddWord(segpt->SegSize);
  rec.AddJstr(segpt->Name);

  OBJfilePt->WriteARecord(rec);
} // end WriteASegDefRec
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// 写一个外部变量定义记录。(外部变量个数<65535)
// 如果没有外部变量,则本记录不写入。
//---------------------------------------------------------------------------
void OBJmodule::WriteAnExtDefRec()
{ OBJrecord EDR(0x19);     // External Definition Record [19H]
  int16u count = 0;
  for( register ExtSymDef* SymPt = ExtSymDefHead;
           SymPt;                     // conditions <==> (SymPt != NULL)
               SymPt = SymPt->next )
   { EDR.AddByte(SymPt->IDBLK);           // ID BLK
     EDR.AddWord(SymPt->ExtID);           // ExtID
     EDR.AddByte(SymPt->LabPt->getTyp());   // SYM INFO
     EDR.AddByte(0x00);                   // unused
     EDR.AddJstr(SymPt->LabPt->LName);    // Name
     ++count;

     if(EDR.GetLEN()> MaxObjRecLength)
      { OBJfilePt->WriteARecord(EDR); EDR.ReNew(0x19); } // endif
   } // end for
  if(count)     // <==> if(count != 0)
   { OBJfilePt->WriteARecord(EDR); } // endif
} // end WriteAnExtDefRec
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// 写一个公共(PUBLIC)变量定义记录。(公共变量个数<65535)
// 如果没有PUBLIC变量,则本记录不写入。
//---------------------------------------------------------------------------
void OBJmodule::WriteAPubDefRec()
{ LabelManager &LM = *(masm.LabMger);
  JLabelNode* tp;

  LM.InitListPtr(tp);
  int16u count = 0;

  OBJrecord PDR(0x17);     // Public Definition Record [17H]
  for( ; LM.GetAPublicLabel(tp); tp = tp->next)
   { PDR.AddWord(tp->RefSeg->SegID);     // SEGID
     PDR.AddByte(tp->getTyp());          // SYM INFO
     PDR.AddWord(tp->Value);             // Offset
     PDR.AddByte(0x00);                  // unused
     PDR.AddJstr(tp->LName);             // Name
     ++count;

     if(PDR.GetLEN()> MaxObjRecLength)
      { OBJfilePt->WriteARecord(PDR); PDR.ReNew(0x17); } // endif
   } // end for
  if(count)     // <==> if(count != 0)
   { OBJfilePt->WriteARecord(PDR); } // endif
} // end WriteAPubDefRec
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// 写一个Debug的段标号记录。   (个数<65535)
// 如果没有SEG变量,则本记录不写入。
//---------------------------------------------------------------------------
void OBJmodule::WriteDebugSegSymRec()
{ if( !Debug ) { return; } // endif
  OBJrecord DSR(0x23);     // Debug Segment symbol Record [23H]
  DSR.AddByte(0x02);       // DEF TYP =[Segment symbols] (0x02)

  ASM_Segment* sgp;

  for(sgp = SegDefHead->next;
          sgp && sgp->SegID == 0;
              sgp = sgp->next); // 从非绝对段开始。

  if(sgp == NULL) { return; } // endif
   // 如果没有可再定位段,返回,本记录不写入。
  for(  ; sgp; sgp = sgp->next )
   { DSR.AddWord(sgp->SegID);            // SEGID
     DSR.AddByte(sgp->SegInfo());        // SEG INFO
     DSR.AddWord(sgp->SegBase);          // Offset
     DSR.AddByte(0x00);                  // unused
     DSR.AddJstr(sgp->Name);             // SEG Name
   } // end for
  OBJfilePt->WriteARecord(DSR);
} // end WriteDebugSegSymRec
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// 写一个Debug的PUBLIC标号记录。   (个数<65535)

⌨️ 快捷键说明

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