📄 hmdlg.cpp
字号:
break;
case MC_ora: //A与[ImmB]进行位或,影响标志位
cpu.a |= mem[mem[cpu.pc]];
cpu.ar= mem[cpu.pc];
increment(cpu.pc);
setflags(cpu.a);
cpu.c = false;
break;
case MC_orx: //A与[X+ImmB]进行位或,影响标志位
cpu.a |= mem[index()];
cpu.ar=index();
increment(cpu.pc);
setflags(cpu.a);
cpu.c = false;
break;
case MC_ori: //A与ImmB进行位或,影响标志位
cpu.a |= mem[cpu.pc];
cpu.ar=cpu.pc;
increment(cpu.pc);
setflags(cpu.a);
cpu.c = false;
break;
case MC_jmp: //绝对跳转到B地址
cpu.ar=cpu.pc;
cpu.pc = mem[cpu.pc];
break;
case MC_bze: //如Z标志为1 则跳转到B 单元去执行,否则顺序执行
if (cpu.z)
{cpu.ar=cpu.pc;
cpu.pc = mem[cpu.pc];
}
else
increment(cpu.pc);
break;
case MC_bnz: //如Z标志为0 则跳转到B 单元去执行,否则顺序执行
if (!cpu.z)
{cpu.ar=cpu.pc;
cpu.pc = mem[cpu.pc];
}
else
increment(cpu.pc);
break;
case MC_bpz: //如P标志为1(正) 则跳转到B 单元去执行,否则顺序执行
if (cpu.p)
{cpu.ar=cpu.pc;
cpu.pc = mem[cpu.pc];
}
else
increment(cpu.pc);
break;
case MC_bng: //如P标志为0(负) 则跳转到B 单元去执行,否则顺序执行
if (!cpu.p)
{cpu.ar=cpu.pc;
cpu.pc = mem[cpu.pc];
}
else
increment(cpu.pc);
break;
case MC_bcs: //如C标志为1 则跳转到B 单元去执行,否则顺序执行
if (cpu.c)
{cpu.ar=cpu.pc;
cpu.pc = mem[cpu.pc];
}
else
increment(cpu.pc);
break;
case MC_bcc: //如C标志为0 则跳转到B 单元去执行,否则顺序执行
if (!cpu.c)
{ cpu.ar=cpu.pc;
cpu.pc = mem[cpu.pc];
}
else
increment(cpu.pc);
break;
case MC_jsr: //调用子程序,返回地址入栈,操作数(JSR的后一字节)B->PC
decrement(cpu.sp);
mem[cpu.sp] = (cpu.pc + 1) % 256; // push return address
cpu.pc = mem[cpu.pc];
break;
case MC_tsp: //单字节指令,将栈指针寄存器SP的内容送入A累加器
cpu.a = cpu.sp;
setflags(cpu.a);
break;
case MC_lbpi: //双字节指令,格式:LBPI B,将由基址指针寄存器BP指示的内存单元起的偏移量为B字节的内存单元的内容送入A
//累加器
cpu.a = mem[cpu.bp + mem[cpu.pc]];
cpu.ar=cpu.bp + mem[cpu.pc];
increment(cpu.pc);
setflags(cpu.a);
break;
case MC_fbpi: //双字节指令,格式:FBPI B,将立即数B送入基址指针寄存器BP
cpu.bp = mem[cpu.pc];
cpu.ar=cpu.pc;
increment(cpu.pc);
break;
case MC_tbp: //单字节指令,将基址指针寄存器BP的内容送入A累加器
cpu.a = cpu.bp;
setflags(cpu.a);
break;
case MC_tsb: //单字节指令,将栈指针寄存器SP的内容送入址指针寄存器BP
cpu.bp = cpu.sp;
break;
case MC_tabp: //单字节指令,将A累加器的内容送入到栈指针寄存器BP中
cpu.bp = cpu.a;
break;
default:
ps = badop;
break;
}
}
/*
对虚拟机执行汇编后的机器指令程序进行执行执行前的准备工作:
argc:用户在命令行上提供的参数个数,据此判断是否以交互方式提示用户输入如下的参数:
trace:设定跟踪标志;datafile:程序的输入数据文件, outfile:程序的输出文件
entrance:机器指令程序的入口点
*/
void CHMDlg::interpret()
{
// bool tracing;
// bool coning;
int entry=0;
cpu.z = false;
cpu.p = false;
cpu.c = false; // 初始化标志器的状态
cpu.a = 0;
cpu.x = 0;
cpu.ar = 0; // 初始化地址寄存器
cpu.sp = 0; // 初始化栈指针寄存器
cpu.bp = 0; // 初始化基址指针寄存器
cpu.pc = 0; // 初始化程序计数器
ps = running; // 初始化cpu的运行状态
//执行机器指令程序
// do
// execute(data,results,tracing); // do it!
// while (ps == running&&coning);
// if (ps != finished)
// runtime_error(results, pcnow);
// if (results != stdout)
// fclose(results);
// if (data != stdin)
// fclose(data);
}
//虚拟机初始化,清空内存,初始机器指令表
void CHMDlg::MC()
{
int i;
//清空内存
for (i = 0; i <= 255; i++)
mem[i] = MC_bad;
// 初始机器指令表
for (i = 0; i <= 255; i++)
mnemonics[i] = "???";
//机器指令表填入对应的汇编助记符 0xxx为机器指令值
mnemonics[MC_nop] = "NOP"; //ox0
mnemonics[MC_clra] = "CLRA"; //ox1
mnemonics[MC_clrc] = "CLRC"; //ox2
mnemonics[MC_clrx] = "CLRX"; //ox3
mnemonics[MC_cmc] = "CMC"; //ox4
mnemonics[MC_inc] = "INC"; //ox5
mnemonics[MC_dec] = "DEC"; //ox6
mnemonics[MC_incx] = "INCX"; //ox7
mnemonics[MC_decx] = "DECX"; //ox8
mnemonics[MC_tax] = "TAX"; //ox9
mnemonics[MC_ini] = "INI"; //oxa
mnemonics[MC_inh] = "INH"; //oxb
mnemonics[MC_inb] = "INB"; //oxc
mnemonics[MC_ina] = "INA"; //oxd
mnemonics[MC_oti] = "OTI"; //oxe
mnemonics[MC_otc] = "OTC"; //oxf
mnemonics[MC_oth] = "OTH"; //ox10
mnemonics[MC_otb] = "OTB"; //ox11
mnemonics[MC_ota] = "OTA"; //ox12
mnemonics[MC_push] = "PUSH"; //ox13
mnemonics[MC_pop] = "POP"; //ox14
mnemonics[MC_shl] = "SHL"; //ox15
mnemonics[MC_shr] = "SHR"; //ox16
mnemonics[MC_ret] = "RET"; //ox17
mnemonics[MC_halt] = "HALT"; //ox18
mnemonics[MC_lda] = "LDA"; //ox19
mnemonics[MC_ldx] = "LDX"; //ox1a
mnemonics[MC_ldi] = "LDI"; //ox1b
mnemonics[MC_lsp] = "LSP"; //ox1c
mnemonics[MC_lspi] = "LSPI"; //ox1d
mnemonics[MC_sta] = "STA"; //ox1e
mnemonics[MC_stx] = "STX"; //ox1f
mnemonics[MC_add] = "ADD"; //ox20
mnemonics[MC_adx] = "ADX"; //ox21
mnemonics[MC_adi] = "ADI"; //ox22
mnemonics[MC_adc] = "ADC"; //ox23
mnemonics[MC_acx] = "ACX"; //ox24
mnemonics[MC_aci] = "ACI"; //ox25
mnemonics[MC_sub] = "SUB"; //ox26
mnemonics[MC_sbx] = "SBX"; //ox27
mnemonics[MC_sbi] = "SBI"; //ox28
mnemonics[MC_sbc] = "SBC"; //ox29
mnemonics[MC_scx] = "SCX"; //ox2a
mnemonics[MC_sci] = "SCI"; //ox2b
mnemonics[MC_cmp] = "CMP"; //ox2c
mnemonics[MC_cpx] = "CPX"; //ox2d
mnemonics[MC_cpi] = "CPI"; //ox2e
mnemonics[MC_ana] = "ANA"; //ox2f
mnemonics[MC_anx] = "ANX"; //ox30
mnemonics[MC_ani] = "ANI"; //ox31
mnemonics[MC_ora] = "ORA"; //ox32
mnemonics[MC_orx] = "ORX"; //ox33
mnemonics[MC_ori] = "ORI"; //ox34
mnemonics[MC_jmp] = "JMP"; //ox35
mnemonics[MC_bze] = "BZE"; //ox36
mnemonics[MC_bnz] = "BNZ"; //ox37
mnemonics[MC_bpz] = "BPZ"; //ox38
mnemonics[MC_bng] = "BNG"; //ox39
mnemonics[MC_bcc] = "BCC"; //ox3a
mnemonics[MC_bcs] = "BCS"; //ox3b
mnemonics[MC_tsp] = "TSP"; //ox3c
mnemonics[MC_jsr] = "JSR"; //ox3d
mnemonics[MC_lbpi] = "LBPI"; //ox3e
mnemonics[MC_fbpi] = "FBPI"; //ox3f
mnemonics[MC_tbp] = "TBP"; //ox40
mnemonics[MC_tsb] = "TSB"; //ox41
mnemonics[MC_tabp] = "TABP"; //ox42
// 初始机器指令长度表
for (i = 0; i <= 255; i++)
mnxlen[i] = 1;
mnxlen[MC_lda] = 2;
mnxlen[MC_ldx] = 2;
mnxlen[MC_ldi] = 2;
mnxlen[MC_lsp] = 2;
mnxlen[MC_lspi] = 2;
mnxlen[MC_sta] = 2;
mnxlen[MC_stx] = 2;
mnxlen[MC_lbpi] = 2;
mnxlen[MC_fbpi] = 2;
mnxlen[MC_add] = 2;
mnxlen[MC_adi] = 2;
mnxlen[MC_adc] = 2;
mnxlen[MC_adx] = 2;
mnxlen[MC_acx] = 2;
mnxlen[MC_aci] = 2;
mnxlen[MC_sub] = 2;
mnxlen[MC_sbx] = 2;
mnxlen[MC_sbi] = 2;
mnxlen[MC_sbc] = 2;
mnxlen[MC_scx] = 2;
mnxlen[MC_sci] = 2;
mnxlen[MC_cmp] = 2;
mnxlen[MC_cpx] = 2;
mnxlen[MC_cpi] = 2;
mnxlen[MC_ana] = 2;
mnxlen[MC_anx] = 2;
mnxlen[MC_ani] = 2;
mnxlen[MC_ora] = 2;
mnxlen[MC_orx] = 2;
mnxlen[MC_ori] = 2;
mnxlen[MC_jmp] = 2;
mnxlen[MC_bze] = 2;
mnxlen[MC_bnz] = 2;
mnxlen[MC_bpz] = 2;
mnxlen[MC_bng] = 2;
mnxlen[MC_bcc] = 2;
mnxlen[MC_bcs] = 2;
mnxlen[MC_jsr] = 2;
}
//把整数转化为16进制字符串
void CHMDlg::itx(int num,char* string1)
{
int temp;
int low=16;
int hight=256;
int i=0;
while(1){
temp=(num%hight)/low;
if(temp<=9)string1[i]=temp+'0';
else string1[i]=temp-10+'A';
if((++i)==2)break;
hight=low;
low/=16;
}
string1[i]=0;
}
//刷新内存
void CHMDlg::showmem()
{
CString tmp_str;
char string3[10];
m_list.DeleteAllItems();//清空显示列表
for(int i=0;i<256;i++)
{
//写入列表
itx(i,string3);
tmp_str=string3;
m_list.InsertItem(i,tmp_str);
itx(mem[i],string3);
tmp_str=string3;
m_list.SetItemText(i,1,tmp_str);
}
}
void CHMDlg::showrtoedit()
{
char bools;
itoa(cpu.pc,bits,10);
m_show_edit+="\r\nPC=";
m_show_edit+=bits;
itoa(cpu.ar,bits,10);
m_show_edit+="\r\nAR=";
m_show_edit+=bits;
itoa(cpu.ir,bits,10);
m_show_edit+="\r\nIR=";
m_show_edit+=bits;
m_show_edit+="\r\nAC=";
itoa(cpu.a,bits,10);
m_show_edit+=bits;
m_show_edit+="\r\nX=";
itoa(cpu.x,bits,10);
m_show_edit+=bits;
m_show_edit+="\r\nSP=";
itoa(cpu.sp,bits,10);
m_show_edit+=bits;
m_show_edit+="\r\n[SP]=";
itoa(mem[cpu.sp],bits,10);
m_show_edit+=bits;
m_show_edit+="\r\nBP=";
itoa(cpu.bp,bits,10);
m_show_edit+=bits;
m_show_edit+="\r\nZ=";
if(cpu.z)
bools='1';
else
bools='0';
m_show_edit+=bools;
m_show_edit+=" P=";
if(cpu.p)
bools='1';
else
bools='0';
m_show_edit+=bools;
m_show_edit+=" C=";
if(cpu.c)
bools='1';
else
bools='0';
m_show_edit+=bools;
m_show_edit+="\r\nOPCODE=";
itoa(cpu.ir,bits,10);
m_show_edit+=bits;
m_show_edit+=" ";
m_show_edit+=mnemonics[cpu.ir];
m_show_edit+="\r\n";
UpdateData(false);
}
void CHMDlg::showr()
{
itb(cpu.pc);
m_pc=bits;
itb(cpu.a);
m_ac=bits;
m_c=cpu.c;
m_p=cpu.p;
m_z=cpu.z;
itb(cpu.ir);
m_ir=bits;
itb(cpu.ar);
m_ir=bits;
UpdateData(false);
}
void CHMDlg::OnBegin()
{
SetTimer(1,100,NULL);
GetDlgItem(IDC_BEGIN)->EnableWindow(FALSE);
GetDlgItem(IDC_CONTINUE)->EnableWindow(FALSE);
GetDlgItem(IDC_OPEN)->EnableWindow(FALSE);
GetDlgItem(IDC_ODD)->EnableWindow(FALSE);
GetDlgItem(IDC_TRACE)->EnableWindow(FALSE);
GetDlgItem(IDC_COMMON)->EnableWindow(FALSE);
// TODO: Add your control notification handler code here
bool errors;
int entry = 0; // 程序执行入口点
//生成一个汇编器对象实例
MC();
m_out="";
m_show_edit="程序开始!";
UpdateData(false);
bool opening;
AS(temp,opening);
if(!opening){
MessageBox("打不开文档");
AAS();
}
//汇编器对源程序代码进行汇编处理,结果存入Machine的内存mem中,
//将汇编过程所出现的错误状态返回给主调函数
else
{
bool wh=assemble(errors);
UpdateData(false);
AAS();
if (errors||!wh)
{
//汇编过程有错误则输出提示信息,退出。
MessageBox("汇编过程有错误!");
}
else
{ m_show_edit+="\r\n汇编正确!程序加载完毕!";
UpdateData(false);
showmem();
GetDlgItem(IDC_NEXT)->EnableWindow(true);
//汇编过程没有错误则执行Machine的内存mem中机器指令。
m_show_edit+="\r\n执行……";
UpdateData(false);
interpret();
//dump memory to src.map
listcode(temp);
}
}
GetDlgItem(IDC_CONTINUE)->EnableWindow(true);
GetDlgItem(IDC_OPEN)->EnableWindow(true);
GetDlgItem(IDC_ODD)->EnableWindow(true);
GetDlgItem(IDC_TRACE)->EnableWindow(true);
GetDlgItem(IDC_COMMON)->EnableWindow(true);
}
void CHMDlg::OnOpen()
{
// TODO: Add your control notification handler code here
//声明一个CFileDialog对象,并设置它的格式
CFileDialog cdlg(true,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"text file(*.asm)|*.asm|All file(*.*)|*.*||",this);
if(cdlg.DoModal() == IDOK)//单击OK按钮
{
//从文件对话框中取得文件名并显示在文本框中
m_doc=cdlg.GetPathName();
temp=new char[m_doc.GetLength() +1];
strcpy(temp,m_doc);
UpdateData(false);//更新
GetDlgItem(IDC_BEGIN)->EnableWindow(true);
}
}
void CHMDlg::OnNext()
{
// TODO: Add your control notification handler code here
int mode=GetCheckedRadioButton(IDC_CONTINUE,IDC_ODD);
int mode2=GetCheckedRadioButton(IDC_TRACE,IDC_COMMON);
if(mode==IDC_CONTINUE )
{
SetTimer(2,2000,NULL);
GetDlgItem(IDC_NEXT)->EnableWindow(false);
while(ps==running){
execute();
//showmem();
showr();
if(mode2==IDC_TRACE)
showrtoedit();
};
showmem();
}
if(ps==running&&mode==IDC_ODD)
{
UpdateData(false);
execute();
showmem();
showr();
if(mode2==IDC_TRACE)
showrtoedit();
}
if(ps!=finished&&ps!=running)
{
int i=0;
runtime_error(cpu.pc);
UpdateData(false);
GetDlgItem(IDC_CONTINUE)->EnableWindow(false);
GetDlgItem(IDC_CONTINUE)->EnableWindow(true);
GetDlgItem(IDC_ODD)->EnableWindow(true);
GetDlgItem(IDC_TRACE)->EnableWindow(true);
GetDlgItem(IDC_COMMON)->EnableWindow(true);
}
if(ps==finished)
{
GetDlgItem(IDC_CONTINUE)->EnableWindow(false);
GetDlgItem(IDC_CONTINUE)->EnableWindow(true);
GetDlgItem(IDC_ODD)->EnableWindow(true);
GetDlgItem(IDC_TRACE)->EnableWindow(true);
GetDlgItem(IDC_COMMON)->EnableWindow(true);
MessageBox("运行结束!");
}
}
void CHMDlg::OnCalldos()
{
// TODO: Add your control notification handler code here
WinExec("虚拟机.exe", SW_SHOW);
}
void CHMDlg::OnOpens()
{
// TODO: Add your command handler code here
CFileDialog cdlg(true,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"text file(*.asm)|*.asm|All file(*.*)|*.*||",this);
if(cdlg.DoModal() == IDOK)//单击OK按钮
{
//从文件对话框中取得文件名并显示在文本框中
m_doc=cdlg.GetPathName();
temp=new char[m_doc.GetLength() +1];
strcpy(temp,m_doc);
UpdateData(false);//更新
}
GetDlgItem(IDC_BEGIN)->EnableWindow(true);
}
void CHMDlg::OnOwner()
{
CAboutDlg A;
A.DoModal();
}
void CHMDlg::OnEdit()
{
// TODO: Add your command handler code here
edit.m_words="";
edit.edited=false;
edit.DoModal();
if(edit.edited==true)
{
temp="EDIT.ASM";
GetDlgItem(IDC_OPEN)->EnableWindow(false);
GetDlgItem(IDC_BEGIN)->EnableWindow(true);
}
}
void CHMDlg::OnHelp()
{
// TODO: Add your command handler code here
ShellExecute(NULL,NULL,_T("虚拟机帮助文件.DOC"),NULL,NULL,SW_SHOWMAXIMIZED);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -