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

📄 myvscpudlg.cpp

📁 模拟cpu的程序原代码
💻 CPP
字号:
// MyVsCpuDlg.cpp : implementation file
//

#include "stdafx.h"
#include "MyVsCpu.h"
#include "MyVsCpuDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// 定义char类型数组表示寄存器存储的二进制数
char AR[6],PC[6],DR[8],AC[8],IR[2];
//定义整形变量表示各寄存器存储值对应的十进制数
int ar,pc,dr,ac,ir;
//64X8的内存
char M[64][8];
//微操作状态
int state=0;
//判断是否第一次输出、是否初始化寄存器、内存
bool first=true,init,initM;
bool chushiHanshu=false;//是否在OnChushi函数中
/////////////////////////////////////////////////////////////////////////////
//这部分为关于对话框
class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
//以下为主对话框 CMyVsCpuDlg dialog
//构造函数
CMyVsCpuDlg::CMyVsCpuDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CMyVsCpuDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CMyVsCpuDlg)
	m_display = _T("");
	m = 0;
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
//数据交换(变量关联)
void CMyVsCpuDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CMyVsCpuDlg)
	DDX_Text(pDX, IDC_EDIT1, m_display);
	DDX_Text(pDX, IDC_EDIT2, m);
	DDV_MinMaxInt(pDX, m, 0, 64);
	//}}AFX_DATA_MAP
}
//菜单、按钮的映射函数
BEGIN_MESSAGE_MAP(CMyVsCpuDlg, CDialog)
	//{{AFX_MSG_MAP(CMyVsCpuDlg)系统调用映射
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//按钮响应映射
	ON_BN_CLICKED(IDZHUANGZAI, OnZhuangzai)
	ON_BN_CLICKED(IDDANBU, OnDanbu)
	ON_BN_CLICKED(IDNEICUN, OnNeicun)
	ON_BN_CLICKED(IDCHUSHI, OnChushi)
	ON_BN_CLICKED(IDQINGKONG, OnQingkong)
	ON_BN_CLICKED(IDCHUSHI2, OnChushi2)
	//菜单响应映射
	ON_COMMAND(ID_MENUDANBU,OnDanbu)
	ON_COMMAND(ID_MENUZHUANGZAI,OnZhuangzai)
	ON_COMMAND(ID_MENUNEIXIAN, OnNeicun)
	ON_COMMAND(ID_MENUCHUSHI, OnChushi)
	ON_COMMAND(ID_MENUQINGKONG, OnQingkong)
	ON_COMMAND(ID_MENUTUICHU,OnCancel)
	ON_COMMAND(ID_MENUBANQUAN,onAbout)
	ON_COMMAND(ID_MENUSHUOMING,OnShuoming)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMyVsCpuDlg message handlers
//初始化对话框
BOOL CMyVsCpuDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	OnChushi();//初始化寄存器和内存
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	CMenu menu;
	menu.LoadMenu (IDR_MENU1);
	//CMenu *myMenu= menu.GetSubMenu (0);
	//myMenu->EnableMenuItem (0,1);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	//SetMenu(myMenu);
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}
//系统菜单
void CMyVsCpuDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}
//画对话框
void CMyVsCpuDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.(系统调用处理)
HCURSOR CMyVsCpuDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}
//把寄存器的二进制值转换为十进制,n为数组长度
int twoto10(char in[],int n)
{
	int r=0,a=0;
	for(int i=n-1;i>=0;i--){
		a=0;
		if(in[i]=='1'){
			a=1;
			for(int j=0;j<n-1-i;j++)
				 a*=2;}
			r+=a;}
	return r;
}
//把int类型转换为char类型(因为显示输出的变量
//m_display为CString类型,int类型不能显示
void intToChar(int t,char &a)
{
	if(t==0)a='0';
	if(t==1)a='1';
	if(t==2)a='2';
	if(t==3)a='3';
	if(t==4)a='4';
	if(t==5)a='5';
	if(t==6)a='6';
	if(t==7)a='7';
	if(t==8)a='8';
	if(t==9)a='9';
}
//把十进制数转换为二进制数,n为数组长度
void tento2(int a,char A[],int n)
{int t;
	for(int i=n-1;i>0;i--){
		t=a%2;
		intToChar(t,A[i]);
		a/=2;
	}
}
//装载程序
void CMyVsCpuDlg::OnZhuangzai() 
{
	CFileDialog f(10);
	CFile file;
	int ok=f.DoModal ();
	if(ok!=IDOK)return;
	CString filename=f.GetPathName();
	char text[1000];
	for(int i=0;i<1000;i++)
		text[i]='0';
	file.Open (filename,2);
	if(!file){MessageBox("不能打开该文件!");return;}
	file.Read (text,1000);
	file.Close ();
	char ss[64][8];
	for(i=0;i<64;i++)
		for(int j=0;j<8;j++)M[i][j]=ss[i][j]='0';
	int k=0;
	while((text[k]!='0')&&(text[k]!='1')&&(text[k]!='\0'))k++;
	for(i=0;(i<64)&&(text[i]!='\0');i++){
		for(int j=0;j<8;j++)
			ss[i][j]=text[k++];
	while((text[k]!='0')&&(text[k]!='1')&&(text[k]!='\0'))k++;	
	}
	UpdateData(true);//读数据
	int fad=m;//初始地址
	if((fad<0)||(fad>63))return;
	int i2=fad;
	pc=m;
	tento2(pc,PC,6);//赋初始地址
	for(i=0;i2<64;i++,i2++)
		for(int j=0;j<8;j++)
			M[i2][j]=ss[i][j];//装载到内存
	//显示打开的文件内容
	m_display="打开的程序文件内容为: \t\t\t\t\t\t";
	m_display+=(char*)text;
	first=true;
	initM=true;
	MessageBox("装载成功!");
	state=0;//状态初始化为0(FETCH1)
	UpdateData(false);//输出数据
}
//单步执行
void CMyVsCpuDlg::OnDanbu() 
{
	if(!init){OnChushi();init=true;
		pc=m;UpdateData(true);}
	run();
	output();//显示寄存器内容
}
//每个状态的微操作
void CMyVsCpuDlg::run()
{
	int i;
	switch(state){
		case 0://FETCH1
			MessageBox("FETCH1");
			ar=pc;tento2(ar,AR,6);
			state++;break;
		case 1:	//FETCH2
			MessageBox("FETCH2");
			for(i=0;i<8;i++)
				DR[i]=M[ar][i];
			dr=twoto10(DR,8);
			pc++;state++;
			if(pc>63){pc=0;}
			tento2(pc,PC,6);
			break;
		case 2://FETCH3
			MessageBox("FETCH3");
			for(i=0;i<2;i++)IR[i]=DR[i];
			for(i=0;i<6;i++)AR[i]=DR[i+2];
			ir=twoto10(IR,2);
			ar=twoto10(AR,6);
			state=8+(int)(IR[0]-'0')*4+(IR[1]-'0')*2;
			break;
		case 8://ADD1
			MessageBox("ADD1");
			for(i=0;i<8;i++)
				DR[i]=M[ar][i];
			dr=twoto10(DR,8);
			//m=dr;
			UpdateData(false);
			state++;
			break;
		case 9://ADD2
			MessageBox("ADD2");
			ac+=twoto10(DR,8);
			UpdateData(false);
			tento2(ac,AC,8);
			state=0;
			break;
		case 10://AND1
			MessageBox("AND1");
			for( i=0;i<8;i++)
				DR[i]=M[ar][i];
			dr=twoto10(DR,8);
			state++;
			break;
		case 11://AND2
			MessageBox("AND2");
			for(i=0;i<8;i++)
				AC[i]=AC[i]&DR[i];
			ac=twoto10(AC,8);
			state=0;
			break;
		case 12://JMP1
			MessageBox("JMP1");
			pc=twoto10(DR,8);
			tento2(pc,PC,6);
			state=0;
			break;
		case 14://INC1
			MessageBox("INC1");
			ac+=1;
			tento2(ac,AC,8);
			state=0;
			break;
		default:
			break;
		}
}
//显示内存
void CMyVsCpuDlg::OnNeicun() 
{	m_display="";
	CString s="00000000";
	for(int i=0;i<64;i++){
		if(i%7==0){
		char s1=(i/10)+'0';
		char s2=(i%10)+'0';
		m_display+=s1;
		m_display+=s2;
		m_display+=":  ";
		}
		for(int j=0;j<8;j++)
			s.SetAt (j,M[i][j]);	
		m_display+=s;
		m_display+=" ";}
	UpdateData(false);
	first=true;
}
//初始化寄存器和内存
void CMyVsCpuDlg::OnChushi() 
{
	chushiHanshu=true;
	init=true;
	first=true;
	for(int i=0;i<6;i++){
		AR[i]=PC[i]='0';
	}	
	for( i=0;i<2;i++){
		IR[i]='0';
	}	
	for( i=0;i<8;i++){
		AC[i]=DR[i]='0';
	}
	ar=pc=dr=ac=ir=0;
	pc=m;
	if(!initM){
		 for(i=0;i<64;i++)
			 for(int j=0;j<8;j++)M[i][j]='0';
		initM=true;}
	if(chushiHanshu){output();chushiHanshu=false;}
}
//输出
void CMyVsCpuDlg::output()
{
	if(first){
		m_display="";
		first=false;}
	CString s1="000000",s2="000000",s3="00000000";
	CString s4="00000000",s5="00";
	for(int i=0;i<6;i++)
	{
		s1.SetAt (i,AR[i]);
		s2.SetAt (i,PC[i]);
	}
	for(  i=0;i<8;i++)
	{
		s3.SetAt (i,DR[i]);
		s4.SetAt (i,AC[i]);
	}
	for( i=0;i<2;i++)
	{
		s5.SetAt (i,IR[i]);
	}
	m_display+="AR:"+s1+"\tPC:"+s2+"\tDR:"+s3+"\tAC:"+s4+"\tIR:"+s5+"\n";
	UpdateData(false);
}
//清空内存
void CMyVsCpuDlg::OnQingkong() 
{
	for(int i=0;i<64;i++)
		for(int j=0;j<8;j++)M[i][j]='0';
	OnNeicun() ;//显示内存
}
//版权菜单响应
void CMyVsCpuDlg::onAbout()
{
	CAboutDlg dlgAbout;
	dlgAbout.DoModal();
}
//显示寄存器数据
void CMyVsCpuDlg::OnChushi2() 
{
	first=true;
	output();
}
//操作说明响应函数
void CMyVsCpuDlg::OnShuoming()
{
	CString s="请先装载程序或初始化,然后按单步执行,";
		s+="之后就可以用鼠标点击'单步执行'按钮或按空格键单步执行!"; 
		s+="装载的文件是用二进制写的程序,每个指令8位。若要指明内存起始";
		s+="地址,则在装载程序前指明。";
	MessageBox(s);
}
//键盘响应
void CMyVsCpuDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	if(nChar==VK_SPACE)
		run();
}

⌨️ 快捷键说明

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