?? objmodule_c.cpp
字號:
//---------------------------------------------------------------------------
//-------- 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 + -