📄 debugcmd.cpp
字号:
// DebugCmd.cpp: implementation of the CDebugCmd class.
//
//////////////////////////////////////////////////////////////////////
#include "Stdafx.h"
#include "DebugCmd.h"
#include "InstructionDef.h"
#include "OperandDef.h"
#include "CodeGenerationDataType.h"
#include "CaslUtil.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDebugCmd::CDebugCmd(CCometVM * argVM /* = NULL */)
{
m_pVM = argVM;
m_iLen = 0;
m_iPos = 0;
m_cszInstruction = NULL;
strcpy(m_szSpace, " ");
}
//-------------设置当前活动的虚拟机----------------------------------
void CDebugCmd::SetActiveVM(CCometVM * argVM)
{
m_pVM = argVM;
}
/////////////////////////////////////////////////////////////////////////
//函数名称:DbgCmd_Assemple
//函数功能:---------------------Assemple功能的执行函数------------------------
//入口参数:U2 argAddress---------------将被进行Assemble的起始内存地址
//出口参数:无
//返回值:int-------------STATUS_OK表示操作成功,其他表示操作失败
//开发人员:杨军
//开发日期:2004-4-23
//修改人员:
//修改日期:
/////////////////////////////////////////////////////////////////////////
int CDebugCmd::DbgCmd_Assemple(U2 argAddress)
{
//unfinished now !!!
//---------------------变量定义部分 begins-----------------------------
ObjectCode objCode;
string strStmt("");
int iRet = 0;
//---------------------变量定义部分 ends -----------------------------
//-----循环接受用户输入的汇编指令,直到用户输入回车符表示结束输入!------
while (1)
{
//参照Debug中的A功能,在输入汇编指令的时候还要加入一定的词法分析的功能!!!!
//-----------输出当前要编辑汇编码的内存地址---------------------------
cout << hex << argAddress << m_szSpace;
//------------接受用户输入的汇编指令----------------------------------
//cin >> strStmt;
cin.sync();
getline(cin, strStmt, '\n');
CaslUtil::Trim(strStmt);
//用户直接按下了回车符,则退出Assemble工作状态
if (strStmt.length() <= 0)
{
break;
}
//将指令转化成大写以便于统一处理
strStmt = strupr(strStmt.begin());
m_cszInstruction = strStmt.c_str();
//-----为GetNextChar函数进行准备---------------------------------------
//获得用户输入的字符串的长度
m_iLen = strlen(m_cszInstruction);
//设置起始字符位置
m_iPos = 0;
//--------------为用户输入的汇编指令生成中间代码结构,为生成目标代码作准备---
iRet = PrepareSingleCaslStmt();
//用户输入的汇编指令有问题
if (STATUS_OK != iRet)
{
//Need to do some error handling operation!!!
cout << "Error In the statement You Input!" << endl;
//继续要求用户在当前内存单元输入汇编指令
continue;
}
//用户输入的汇编指令合法
else
{
//---用户输入的Casl指令是合法的,则为其生成目标代码,----------------------
//---并将生成的目标代码放入当前内存单元中去------------------------------
//为用户输入的Casl源程序生成目标代码
memset(&objCode, 0, sizeof(objCode) / sizeof(char));
switch (m_asmCode.instType)
{
//-----------对宏指令IN要生成三条Casl指令--------------------------------
case CASL_IN:
//生成指令Set_ALabel
objCode.instructionType = CASL_SET_ALABEL;
objCode.regNumber = REG_EMPTY;
objCode.regNumber <<= 4;
objCode.regNumber = REG_EMPTY;
if (m_asmCode.bALabelAddress)
{
(*(S2*)objCode.address) = m_asmCode.s2ALabelAddress;
}
//将生成的目标代码放入内存单元中去
memcpy(m_pVM->m_pVMMemoryBase + argAddress, &objCode, sizeof(objCode) / sizeof(char));
argAddress += 2;
//生成指令Set_NLabel
objCode.instructionType = CASL_SET_NLABEL;
objCode.regNumber = REG_EMPTY;
objCode.regNumber <<= 4;
objCode.regNumber = REG_EMPTY;
if (m_asmCode.bNLabelAddress)
{
(*(S2*)objCode.address) = m_asmCode.s2NLabelAddress;
}
//将生成的目标代码放入内存单元中去
memcpy(m_pVM->m_pVMMemoryBase + argAddress, &objCode, sizeof(objCode) / sizeof(char));
argAddress += 2;
//生成指令Func_In
objCode.instructionType = CASL_FUNC_IN;
objCode.regNumber = REG_EMPTY;
objCode.regNumber <<= 4;
objCode.regNumber = REG_EMPTY;
//将生成的目标代码放入内存单元中去
memcpy(m_pVM->m_pVMMemoryBase + argAddress, &objCode, sizeof(objCode) / sizeof(char));
argAddress += 2;
break;
//-----------对宏指令OUT要生成三条Casl指令--------------------------------
case CASL_OUT:
//生成指令Set_ALabel
objCode.instructionType = CASL_SET_ALABEL;
objCode.regNumber = REG_EMPTY;
objCode.regNumber <<= 4;
objCode.regNumber = REG_EMPTY;
if (m_asmCode.bALabelAddress)
{
(*(S2*)objCode.address) = m_asmCode.s2ALabelAddress;
}
//将生成的目标代码放入内存单元中去
memcpy(m_pVM->m_pVMMemoryBase + argAddress, &objCode, sizeof(objCode) / sizeof(char));
argAddress += 2;
//生成指令Set_NLabel
objCode.instructionType = CASL_SET_NLABEL;
objCode.regNumber = REG_EMPTY;
objCode.regNumber <<= 4;
objCode.regNumber = REG_EMPTY;
if (m_asmCode.bNLabelAddress)
{
(*(S2*)objCode.address) = m_asmCode.s2NLabelAddress;
}
//将生成的目标代码放入内存单元中去
memcpy(m_pVM->m_pVMMemoryBase + argAddress, &objCode, sizeof(objCode) / sizeof(char));
argAddress += 2;
//生成指令Func_In
objCode.instructionType = CASL_FUNC_OUT;
objCode.regNumber = REG_EMPTY;
objCode.regNumber <<= 4;
objCode.regNumber = REG_EMPTY;
//将生成的目标代码放入内存单元中去
memcpy(m_pVM->m_pVMMemoryBase + argAddress, &objCode, sizeof(objCode) / sizeof(char));
argAddress += 2;
break;
default:
objCode.instructionType = m_asmCode.instType;
if (m_asmCode.bXRUse)
{
//变址寄存器的编号放在regNumber的高四位
objCode.regNumber |= m_asmCode.iXRNumber;
}
else
{
objCode.regNumber |= REG_EMPTY;
}
objCode.regNumber <<= 4;
if (m_asmCode.bGRUse)
{
//通用寄存器编号放在regNumber的低四位
objCode.regNumber |= m_asmCode.iGRNumber;
}
else
{
objCode.regNumber |= REG_EMPTY;
}
if (m_asmCode.bAddressUse)
{
(*(S2*)objCode.address) = m_asmCode.s2Address;
}
//将生成的目标代码放入内存单元中去
memcpy(m_pVM->m_pVMMemoryBase + argAddress, &objCode, sizeof(objCode) / sizeof(char));
//因为一条Casl目标指令占两个字长,所以内存地址加2
argAddress += 2;
}
}
}
return STATUS_OK;
}
/////////////////////////////////////////////////////////////////////////
//函数名称:CheckSingleCaslStmt
//函数功能:检测用户输入的一条Casl源程序是否符合Casl语言的文法标准
//入口参数:无
//出口参数:无
//返回值:int-------------STATUS_OK表示操作成功,其他表示操作失败
//开发人员:杨军
//开发日期:2004-4-23
//修改人员:
//修改日期:
/////////////////////////////////////////////////////////////////////////
int CDebugCmd::CheckSingleCaslStmt()
{
//--------------------变量定义部分begins---------------
//--------------------变量定义部分ends ---------------
//-----将指令按第一个字母来分类处理--------------------
switch (GetNextChar())
{
case 'A': //AND, ADD ?
if (STATUS_OK != Instruction_HeadedByA())
{
goto CheckSingleStmtFailed;
}
break;
case 'C': //CPA, CPL, CALL ?
if (STATUS_OK != Instruction_HeadedByC())
{
goto CheckSingleStmtFailed;
}
break;
case 'E': //EOR ?
if (STATUS_OK != Instruction_HeadedByE())
{
goto CheckSingleStmtFailed;
}
break;
case 'I': //IN ?
if (STATUS_OK != Instruction_HeadedByI())
{
goto CheckSingleStmtFailed;
}
break;
case 'J': //JMP, JPZ, JMI, JNZ, JZE ?
if (STATUS_OK != Instruction_HeadedByJ())
{
goto CheckSingleStmtFailed;
}
break;
case 'L': //LD, LEA ?
if (STATUS_OK != Instruction_HeadedByL())
{
goto CheckSingleStmtFailed;
}
break;
case 'O': //OR, OUT ?
if (STATUS_OK != Instruction_HeadedByO())
{
goto CheckSingleStmtFailed;
}
break;
case 'P': //PUSH, POP ?
if (STATUS_OK != Instruction_HeadedByP())
{
goto CheckSingleStmtFailed;
}
break;
case 'R': //RET ?
if (STATUS_OK != Instruction_HeadedByR())
{
goto CheckSingleStmtFailed;
}
break;
case 'S': //ST, SUB, SLA, SRA, SLL, SRL
if (STATUS_OK != Instruction_HeadedByS())
{
goto CheckSingleStmtFailed;
}
break;
default: //Other
goto CheckSingleStmtFailed;
break;
}
m_pVM->m_errorHandler.WriteErrorMessage("CheckSingleStmt Successfully!");
return STATUS_OK;
CheckSingleStmtFailed:
m_pVM->m_errorHandler.WriteErrorMessage("CheckSingleStmt Failed!");
return STATUS_FAILED;
}
/////////////////////////////////////////////////////////////////////////
//函数名称:PrepareSingleCaslStmt
//函数功能:---------------------产生一条源程序指令的中间代码,为生成目标代码
// 进行准备----------------------------------
//入口参数:无
//出口参数: 无
//返回值:int-------------STATUS_OK表示操作成功,其他表示操作失败
//开发人员:杨军
//开发日期:2004-4-24
//修改人员:
//修改日期:
/////////////////////////////////////////////////////////////////////////
int CDebugCmd::PrepareSingleCaslStmt()
{
m_asmCode.bAddressUse = false;
m_asmCode.bALabelAddress = false;
m_asmCode.bGRUse = false;
m_asmCode.bNLabelAddress = false;
m_asmCode.bXRUse = false;
//--------------检测用户输入的汇编指令的格式是否正确--------------------
//用户输入的汇编指令有问题
if (STATUS_OK != CheckSingleCaslStmt())
{
return STATUS_FAILED;
}
//用户输入的汇编指令合法
else
{
}
return STATUS_OK;
}
/////////////////////////////////////////////////////////////////////////
//函数名称:GetNextChar
//函数功能:-----用于A命令中获得用户输入的指令串的下一个字符,并改变索引指针-------
//入口参数:无
//出口参数:无
//返回值:char--------------------------------指令串中的下一个字符,如果已经读到末尾,就返回EOI标志
//开发人员:杨军
//开发日期:2004-4-24
//修改人员:
//修改日期:
/////////////////////////////////////////////////////////////////////////
char CDebugCmd::GetNextChar()
{
if (m_iPos >= m_iLen)
{
return EOI;
}
return m_cszInstruction[m_iPos++];
}
/////////////////////////////////////////////////////////////////////////
//函数名称:Instruction_HeadedByA
//函数功能:---------------------处理以字符A作为起始字符的指令----------------
//入口参数:无
//出口参数:无
//返回值:int-------------STATUS_OK表示操作成功,其他表示操作失败
//开发人员:杨军
//开发日期:2004-4-24
//修改人员:
//修改日期:
/////////////////////////////////////////////////////////////////////////
int CDebugCmd::Instruction_HeadedByA()
{
switch (GetNextChar())
{
case 'N': //AND ?
//得到AND输入
if ('D' == GetNextChar())
{
m_asmCode.instType = CASL_AND;
//注意: 指令后必须跟至少一个空格才能再跟操作数!!
// 否则视为不合法!!!
if (' ' == GetNextChar())
{
//略过多余的空格
PassBySpace();
if (STATUS_OK != HandleGRAndEA())
{
goto Instruction_HeadedByA_Failed;
}
}
else
{
goto Instruction_HeadedByA_Failed;
}
}
//不支持的输入
else
{
goto Instruction_HeadedByA_Failed;
}
break;
case 'D': //ADD ?
//得到ADD输入
if ('D' == GetNextChar())
{
m_asmCode.instType = CASL_ADD;
if (' ' == GetNextChar())
{
//略过多余的空格
PassBySpace();
if (STATUS_OK != HandleGRAndEA())
{
goto Instruction_HeadedByA_Failed;
}
}
else
{
goto Instruction_HeadedByA_Failed;
}
}
//不支持的输入
else
{
goto Instruction_HeadedByA_Failed;
}
break;
default: //Other
goto Instruction_HeadedByA_Failed;
break;
}
return STATUS_OK;
//--------------错误处理部分----------------------------------------------------------
Instruction_HeadedByA_Failed:
m_pVM->m_errorHandler.WriteErrorMessage("Unknown Instruction!");
return STATUS_FAILED;
}
/////////////////////////////////////////////////////////////////////////
//函数名称:Instruction_HeadedByC
//函数功能:---------------------处理以字符C作为起始字符的指令----------------
//入口参数:无
//出口参数:无
//返回值:int-------------STATUS_OK表示操作成功,其他表示操作失败
//开发人员:杨军
//开发日期:2004-4-24
//修改人员:
//修改日期:
/////////////////////////////////////////////////////////////////////////
int CDebugCmd::Instruction_HeadedByC()
{
//CPA, CPL, CALL ?
switch (GetNextChar())
{
case 'P': //CPA OR CPL?
switch (GetNextChar())
{
case 'A': //CPA
m_asmCode.instType = CASL_CPA;
break;
case 'L': //CPL
m_asmCode.instType = CASL_CPL;
break;
default: //不支持的输入
goto Instruction_HeadedByC_Failed;
break;
}
//处理操作数
if (' ' == GetNextChar())
{
//略过多余的空格
PassBySpace();
if (STATUS_OK != HandleGRAndEA())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -