📄 caslutil.cpp
字号:
if (!strcmp(argVec[i].strLabelName, argLabelName))
{
return i;
}
}
return -1;
}
//////////////////////////////////////////////////////////////////
//函数名称:LookUpInConstLableTable
//函数功能:在常量标号表中查询有无指定的常量标号记录
//入口参数:vector<ConstLabelItem>& argVec---------------------常量标号表
// const CaslString argLabelName----------------------待查询的标号名称
//出口参数:无
//返回值:int---------------- >= 0 表示找到的指定的标号记录在常量标号表中的编号,< 0 表示未找到
//开发人员:杨军
//开发日期:2004-3-18
//修改人员:
//修改日期:
//////////////////////////////////////////////////////////////////
int LookUpInConstLableTable(vector<ConstLabelItem>& argVec, const CaslString argLabelName)
{
//----------------------变量定义部分begins----------------------
size_t i = 0;
size_t uiSize =0;
//----------------------变量定义部分ends----------------------
uiSize = argVec.size();
for (i = 0; i < uiSize; i++)
{
if (!strcmp(argVec[i].strLabelName, argLabelName))
{
return i;
}
}
return -1;
}
//////////////////////////////////////////////////////////////////
//函数名称:LookUpInInstructionLableTable
//函数功能:在指令标号表中查询有无指定的指令标号记录
//入口参数:vector<InstructionLabelItem>& argVec---------------------指令标号表
// const CaslString argLabelName----------------------待查询的标号名称
//出口参数:无
//返回值:int---------------- >= 0 表示找到的指定的标号记录在指令标号表中的编号,< 0 表示未找到
//开发人员:杨军
//开发日期:2004-3-18
//修改人员:
//修改日期:
//////////////////////////////////////////////////////////////////
int LookUpInInstructionLableTable(vector<InstructionLabelItem>& argVec, const CaslString argLabelName)
{
//----------------------变量定义部分begins----------------------
size_t i = 0;
size_t uiSize =0;
//----------------------变量定义部分ends----------------------
uiSize = argVec.size();
for (i = 0; i < uiSize; i++)
{
if (!strcmp(argVec[i].strLabelName, argLabelName))
{
return i;
}
}
return -1;
}
//完成Casl编译器工作前的一些初始化工作
//如设置全局变量的默认值等
CaslUtilStatus CaslCompilerInitialize()
{
char szVal[5];
//----------初始化单指令操作数的指令的名称数组 begins-------------
strcpy(szVal, "JMP");
g_vecSingleOperandInstructionName.push_back(szVal);
strcpy(szVal, "JPZ");
g_vecSingleOperandInstructionName.push_back(szVal);
strcpy(szVal, "JMI");
g_vecSingleOperandInstructionName.push_back(szVal);
strcpy(szVal, "JNZ");
g_vecSingleOperandInstructionName.push_back(szVal);
strcpy(szVal, "JZE");
g_vecSingleOperandInstructionName.push_back(szVal);
strcpy(szVal, "PUSH");
g_vecSingleOperandInstructionName.push_back(szVal);
strcpy(szVal, "POP");
g_vecSingleOperandInstructionName.push_back(szVal);
strcpy(szVal, "CALL");
g_vecSingleOperandInstructionName.push_back(szVal);
strcpy(szVal, "SET_NLABEL");
g_vecSingleOperandInstructionName.push_back(szVal);
strcpy(szVal, "SET_ALABEL");
g_vecSingleOperandInstructionName.push_back(szVal);
//----------初始化单指令操作数的指令的名称数组 ends-------------
//----------初始化不使用操作数的指令的名称数组 begins-------------
strcpy(szVal, "RET");
g_vecNoOperandInstructionName.push_back(szVal);
strcpy(szVal, "FUNC_IN");
g_vecNoOperandInstructionName.push_back(szVal);
strcpy(szVal, "FUNC_OUT");
g_vecNoOperandInstructionName.push_back(szVal);
strcpy(szVal, "EXIT");
g_vecNoOperandInstructionName.push_back(szVal);
//----------初始化不使用操作数的指令的名称数组 ends-------------
return CASL_UTIL_OP_OK;
}
//////////////////////////////////////////////////////////////////
//函数名称:<<
//函数功能:自定义文件流输出operator,用于向文件流中输出一个目标代码数据
//入口参数:无
//出口参数:无
//返回值:无
//开发人员:杨军
//开发日期:2004-3-19
//修改人员:
//修改日期:
//////////////////////////////////////////////////////////////////
CaslOFStream& operator << (CaslOFStream& outStream, ObjectCode argData)
{
outStream << argData.instructionType;
outStream << argData.regNumber;
outStream << argData.address[0];
outStream << argData.address[1];
return outStream;
}
//////////////////////////////////////////////////////////////////
//函数名称:<<
//函数功能:自定义文件流输入operator,用于从文件流中读入一个目标代码数据
//入口参数:无
//出口参数:无
//返回值:无
//开发人员:杨军
//开发日期:2004-3-19
//修改人员:
//修改日期:
//////////////////////////////////////////////////////////////////
CaslIFStream& operator >> (CaslIFStream& inStream, ObjectCode& argData)
{
//inStream >> argData.instructionType;
inStream.read((char*)&argData.instructionType, 1);
inStream.read((char*)&argData.regNumber, 1);
inStream.read((char*)argData.address, 2);
//inStream >> argData.regNumber;
//inStream >> argData.address[0];
//inStream >> argData.address[1];
return inStream;
}
//////////////////////////////////////////////////////////////////
//函数名称:WriteExeFile
//函数功能:以当前的目标代码和常量表及变量表生成指定名称的Casl程序的可执行文件
//入口参数:string szFileName---------------------要生成的可执行文件的名称
//出口参数:无
//返回值:CaslUtilStatus----------------操作状态,CASL_UTIL_OP_OK表示操作成功,其他表示操作失败
//开发人员:杨军
//开发日期:2004-3-19
//修改人员:
//修改日期:
//////////////////////////////////////////////////////////////////
CaslUtilStatus WriteExeFile(string szFileName)
{
//为了保证平台无关性,这一部分采用标准的C++流输出
//----------------------变量定义部分begins----------------------
CaslExeHeader exeHeader;
CaslOFStream ofOut(szFileName.c_str(), ios::out | ios::binary | ios::trunc);
//如果打开文件失败的话
if (!ofOut)
{
cout << "创建文件" << szFileName << "failed " << endl;
return OPEN_FILE_FAILED;
}
size_t i = 0;
size_t uiSize = 0;
U2 u2Temp1 = 0;
U2 u2Temp2 = 0;
unsigned char * pTemp = NULL;
//----------------------变量定义部分ends--------------------------
//初始化可执行文件头部数据
//注意我们这里在计算大小,偏移时都是以字(16 bits)为单位
//设置可执行文件的常量区域大小
exeHeader.constAreaSize = g_iConstSize;
//设置可执行文件中的可视化调试信息大小
exeHeader.iVisualDebugInfoSize = g_vecVisualDebugInfo.size() * sizeof(InstructionDebugInfo);
//设置可执行文件中的变量区域大小
exeHeader.variableAreaSize = g_iVariableSize;
//设置可执行文件中的执行入口点
exeHeader.entryPoint = g_iConstSize + g_iVariableSize + exeHeader.iVisualDebugInfoSize;
//将文件头写入目标文件中
ofOut << exeHeader.entryPoint;
ofOut << exeHeader.iVisualDebugInfoSize;
ofOut << exeHeader.variableAreaSize;
ofOut << exeHeader.constAreaSize;
#ifdef DEBUG_MODE
cout << "entry point(Write):" << exeHeader.entryPoint << endl;
cout << "variable area size(Write):" << exeHeader.variableAreaSize << endl;
cout << "size of const area(Write):" << exeHeader.constAreaSize << endl;
#endif
//紧随文件头写入可视化调试信息
uiSize = g_vecVisualDebugInfo.size();
for (i = 0; i < uiSize; i++)
{
//每条调试信息都是一个二元组
//先写入源程序行号
ofOut << g_vecVisualDebugInfo[i].u2SrcCodeLineNumber;
//再写入目标代码在目标程序中的可执行代码序号
ofOut << g_vecVisualDebugInfo[i].u2InstructionNumber;
}
//对于变量信息只需要在文件头中记录变量区域的大小
//然后在虚拟机中装入可执行文件时再分配变量空间即可
//而对于常量区域则需要将常量数据全部写入目标文件中
//在向目标文件中写入数据的时候可以按int ,char型写入
//而在虚拟机执行装入可执行文件模块时则需要
//将int型数据转化为Double Byte数据存放
//将char扩充为double Byte数据存放
//目前在写入目标文件的时候已经进行了double Byte的扩充
//所以在从目标文件中载入虚拟机内存时就可以比较方便地完成了!!!!
//一定要注意此处!!!!!!
uiSize = g_vecConst.size();
for (i = 0; i < uiSize; i++)
{
switch (g_vecConst[i].type)
{
case DEC_CONST:
//pTemp = (unsigned char*)&g_vecConst[i].constData.decVal;
//ofOut << *pTemp << *(pTemp + 1);
ofOut << g_vecConst[i].constData.decVal;
break;
case HEX_CONST:
//pTemp = (unsigned char*)&g_vecConst[i].constData.hexVal;
//ofOut << *pTemp << *(pTemp + 1);
ofOut << g_vecConst[i].constData.hexVal;
break;
case LABEL_CONST:
//ofOut << g_vecConst[i].constData.labelVal;
ofOut << g_vecConstLabel[i].iOffset;
break;
case STR_CONST:
ofOut << g_vecConst[i].constData.strVal;
break;
}
}
//将可执行代码写入目标文件中
uiSize = g_vecObjectCode.size();
#ifdef DEBUG_MODE
cout << "被写入文件中的目标代码条数:" << uiSize << endl;
#endif
for (i = 0; i < uiSize; i++)
{
ofOut << g_vecObjectCode[i];
}
ofOut.close();
#ifdef DEBUG_MODE
//debug use --------------------------------------------begins
CaslIFStream inFile(szFileName.c_str());
//打开文件失败的话
if (!inFile.is_open())
{
cout << "Open " << szFileName << "failed!" << endl;
return OPEN_FILE_FAILED;
}
exeHeader.entryPoint = 0;
exeHeader.iVisualDebugInfoSize = 0;
exeHeader.constAreaSize = 0;
exeHeader.variableAreaSize = 0;
//读入可执行文件头部信息
inFile >> exeHeader;
cout << "entry point(Read):" << exeHeader.entryPoint << endl;
cout << "size of Visual Debugging Info(Read):" << exeHeader.iVisualDebugInfoSize << endl;
cout << "variable area size(Read):" << exeHeader.variableAreaSize << endl;
cout << "size of const area(Read):" << exeHeader.constAreaSize << endl;
//--------------------读入可视化调试信息----------------------------------
//计算出可视化调试信息的记录条数
uiSize = exeHeader.iVisualDebugInfoSize / sizeof(InstructionDebugInfo);
g_vecVisualDebugInfo.clear();
for (i = 0; i < uiSize; i++)
{
inFile >> u2Temp1;
inFile >> u2Temp2;
g_vecVisualDebugInfo.push_back(InstructionDebugInfo(u2Temp1, u2Temp2));
}
char chTemp;
cout << hex;
for (i = 0; i < (size_t)exeHeader.constAreaSize; i++)
{
inFile >> chTemp;
cout << (int)chTemp << endl;
inFile >> chTemp;
cout << (int)chTemp << endl;
}
cout << dec;
//读入目标代码
vector<ObjectCode> vecObjCode;
ObjectCode objCode;
unsigned char regNumber;
while (1)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -