简单模型机的设计与实现

计算机原理

课程设计

课程名称:       计算机原理       

指导教师:        于复兴          

姓    名:        王亚松          

班    级:        20计4          

学    号:     202014600113       

日    期:       2022.6.1         

                    人 工 智 能 学 院

一、设计题目

简单模型机的设计与实现

  • 设计要求

存储器的地址总线和数据总线宽度均为16位。

CPU使用流水线技术,流水级数为5级,分别是:取指、译码、执行、访存、写回。

输入要求:界面文本框输入;或者文件输入从文件test.data读入汇编执行

输出要求:模拟器用txt文件记录每一个周期CPU主要寄存器的值,总线数值,程序执行完毕后,用txt文件记录数据存储器的内容。记录数据时要注意对齐。同时界面显示。

基本功能:完成课本模型机基本指令串行执行过程描述。将指令分解成微指令。可视化展示指令执行过程,寻址方式只有000 寄存器寻址

三、设计过程

1、根据需求分析的结果,系统总体结构如图1所示。

图 1 系统总体结构

对计算机模型机设计的系统,主要划分为以下五个模块:

  1. CPU:运算部件以及寄存器组织。

PC寄存器,复位时的值为0,通过ALU实现增1操作。16位宽8个通用寄存器(R0~R7),对应地址为0~7,复位时的值为0,8位宽。一个程序状态寄存器(PSW,对应地址为8),8位宽。通用寄存器、程序状态寄存器和数据存储器统一编址,通用寄存器既可以用寄存器号访问,也可以用地址空间的地址访问。

2)指令格式:指令系统采用变长指令格式,基本指令字长16位,其中OP为操作码4位,可定义16种操作。M为寻址方式,MS为源操作数寻址方式,MD为目的操作数寻址方式,RS 为源操作数寄存器,RD为目的操作数寄存器。MS、RS,配合可确定源操作数,MD、RS,配合可确定目的操作数。

3) 读取指令后将介绍模拟器包括PC寄存器(存放下一条指令的地址)、通用寄存器(传送和暂存数据)、指令存储器(暂存当前要执行的指令,地址总线存放指令地址,数据总线存放指令)、数据存储器(暂存从文件读出的数据,地址总线存放数据地址,数据总线存放二进制数据)、程序状态寄存器、指令寄存器IR。

可执行的指令格式有以下几种:

ADD:加法指令 ADD Rd,Rr

SUB:减法指令 SUB Rd,Rr

MUL:无符号乘法指令 MUL Rd,Rr

RJMP:无条件相对跳转指令 RJMP K

BRMI:有条件相对跳转指令 BRMI K

MOV:数据传送指令 MOV Rd,Rr

LDI:载入立即数指令 LDI Rd,K

LD:装载指令 LD Rd,X

ST:存储指令 ST X.Rr

NOP:空操作指令 NOP

4)  寻址方式分配

(1)寄存器寻址:寻址方式000,汇编符号R,(R)为操作数。

(2)寄存器间址:寻址方式001,汇编符号(R),有效地址E = (R)。

(3)自增型寄存器间址:寻址方式010,汇编符号(R)+,E =(R)且(R)+ 1->R。

(4)自增型双间址:寻址方式011,汇编符号@(R)+,E = ((R))且(R)+1->R。

(5)变址寻址:寻址方式100,汇编符号X(R),E = X+R。

其中自增型寄存器间址除按寄存器间址取出操作数外还要修改寄存器的内容,让寄存器的内容增1后仍送到该寄存器。自增型双间址是指寄存器的内容不是操作数的地址,而是操作数地址的地址,同时要修改寄存器的内容。变址寻址是以指令的下一单元的内容作为位移量X,与寄存器的内容相加作为操作数的地址。

  1. 机器周期:

根据各类指令执行的需要,机器设置四个机器周期,用四个触发器作为标志。某一时期内只能有其中一个触发器状态为1,指明CPU现在所处的执行指令的阶段,为该阶段的工作提供依据。

(1)取指周期(FT):取指周期完成取指令的工作,这是每条指令都必须经历的。在FT中完成的操作与指令的操作码无关。取指周期结束后将转向哪个周期,则与FT中取出的指令类型有关。

(2)取源操作数周期(ST):如果需要从主存中读取源操作数,则进人ST。在ST中将根据指令寄存器IR中的源地址字段形成源操作数地址,读取源操作数送SR。

(3)取目的操作数周期(DT):如果需要从主存中读取目的操作数,则进入DT,在DT中将依据IR中的目的地址字段形成目的操作数地址,读取目的操作数送DR。

(4)执行周期(ET):所有指令都进人该周期,这是各类指令都需经历的最后一个工作阶断,在ET中将根据IR中的操作码执行相应的操作。

  1. 详细设计
  1. 系统包含的类库

using System;

using System.IO;

using System.Text;

using System.Text.RegularExpressions;

using System.Windows.Forms;

(2)各个变量的定义和作用

private int i = -1;          //listbox_Jiqi所选中项

private int mi = 0;         //内存单元被选中的项,即地址

  private int ui = -1;         //指令周期

  private int q = 0;

  private bool all = false;

  private string asmIns;      //提取的指令

  private string PCbaoliu;

  private string[] insSplits;    //指令分割

  private string result;

  1. 系统函数的组成、功能、参数说明、相互调用关系

构造函数 Form()

调用InitializeComponent()方法,对窗体和各个控件进行初始化。

单步执行函数 void btn_Peri_Click(object sender, EventArgs e)

这是一个有参的函数, 通过挪动存有汇编指令和机器指令的的listBox的SelectedIndex来进行单步执行的操作。

加载文件函数 void btn_File_Click(object sender, EventArgs e)

这是一个有参函数,主要通过打开文件对话框,设置过滤器可以导入txt和data文件。

指令转换函数string whichRegCode(string regExpr)

这是一个有参函数,主要功能是加载指定的文件,读取文件中的指令,将汇编指令转换为对应的机器指令。

编码转换函数string decToBCD(int dec)

将十进制转换为BCD码

复位监听函数btn_Reset_Click(object sender, EventArgs e)

这个函数的功能主要是重置机器指令集和汇编指令集。

操作数自加函数selfIncrease(string hexNum, bool isPC)

这是一个有参函数,主要功能是完成寄存器内操作数自加操作。

获取寻址函数string whichMethodCode(string regExpr)

这是一个有参函数,通过匹配不同的寻址方式,返回不同的标志位。

4、设计测试流程

  1. 点击Visual Studio 2017中的启动按钮,进入系统,本次测试是在环境中执行(实际上可以直接点击exe文件执行),启动成功后,进入本项目界面,显示本系统相关信息。如图2所示。

图 2 系统主页

(2)根据系统提示,点击打开文件按钮,选择放置好的test.data测试文件。如图3所示。

图 3 读入测试数据

(3)点击单步执行按钮,我们可以观察到位置列序列的变化。初始选中汇编指令、机器码以及周期的的一个。对整套汇编指令进行按行运算,最后一个运算的结果记录在主存单元中。如图4所示。

图 4 单步执行

  1. 全部执行,会显示已执行完毕!汇编指令被导入,CPU指令集实现。其中,包含着:数据传送指令:格式为MOV Rd , Rs。其中Rd为目的操作数寄存器,Rs为原操作数寄存器,其功能是:Rd <- Rs,操作码0001。寄存器组与老师给的测试文件分析中一致,即为正确。如图5所示。

图 5 全部执行

  1. 中止,会停留在中止时执行到的地方。如图6所示。

图 6 中止

(6)点击重置按钮后,数据全部清零,每一条汇编指令按行对应一条机器指令,运行结果如图7所示。

图 7 重置

(7)以上就是全部测试内容,测试完毕后,请自行关闭界面,返回即可。

四、设计中遇到的问题和解决方案

1.难点分析

一个项目的开发过程并不总是一帆风顺的,其中难免会遇到困难,使编程无法继续下去。例如代码部分较混乱,原理理解不透彻,指令读取问题,程序计数器(PC)在执行完一条指令后进行+1操作,发现最终结果不对,数组越界问题,还有进制转换问题。

2.解决方案

针对程序设计过程中遇到的困难,我采取了积极有效的解决方法:上网搜索资料以及观看视频自行理解。首先,导入text.data文件,在这里显示就发生了问题,需要把文件中的括号改为英文模式才能得以显示。对汇编指令进行读取再转为机器指令,在这过程中,我所用到的方法是运用switch()语句将汇编指令转化为机器指令,但是会出未读取的情况,经过检测是因为字符串符号的问题,其实这就是一个字符串的匹配问题。在编写将已被赋值的寄存器中的数据送入到另一个寄存器中时,由于对switch()语句的不熟悉,以及目的操作数寄存器和源操作寄存器的逻辑关系的混乱导致在程序运行时不仅将源操作数寄存器送入到目的操作数寄存器中的数据在界面上得不到显示,在最先被赋值的寄存器中的数据也无显示,现已得到解决。此案例因为每条指令占两个字节,书中所言+1操作,实际应每次+2。在编写运算部分时,会出现“索引超出了数组界限”和“索引超出范围,必须为非负值并小于集合大小”的异常,通过不断测试以及更改,发现是我在对机器指令进行运算时对目的操作数寄存器和源操作数寄存器的赋值上出现了逻辑问题由于通用寄存器长度为十六位,但有时数据译成二进制字符串后,长度往往会出现不够的情况,当字符串长度不够时,补零。经过反复的调试,最终把问题全部解决。

3.测试结果

程序在Visual Studio 2015中运行测试,能实现预期的功能,项目完工!

五、设计感触

通过这一学期的学习,以及这几周对课程的设计,我收获颇多。本项目加深了对计算机原理知识的了解与认识。通过本次模型机的课程设计,明白数据在计算机中的操作过程,对算术运算的相关术语,清楚的了解了CPU基本工作原理。掌握运算器的工作流程。实现简单运算器的数据传送通路,并结合给定数据,完成指定的运算过程,初步了解运算器在计算机整机中的作用。

还记得刚开始着手准备,由于计算机涉及的部件比较多,结构原理比较复杂,反复听视频,记笔记最终也未能有很好的收获,对于初学者来说真的无从下手,所以在整个过程设计中,是由由浅到深、由简到繁,一步步设计出来的。从最开始的界面搭建,就用了一天的时间,还要考虑如何呈现的问题,对于Visual Studio中的许多控件还是特别的不熟悉。不过,通过一步步的设计与学习,慢慢能清楚了解计算机的基本组成,基本原理和设计步骤,慢慢有了思路,最终能建立起整体的概念,为独立完成课程设计奠定了良好的基础。

课程设计结束了,虽然一些部分功能还是未达到老师所给的需求,但是我在从中学习不少的计算机原理有关的知识,虽然看视频也能吸收一部分,但是这往往是不够的,还是要不断实践摸索这其中的奥秘。本次设计是一个简单的模型机,由运算器、一个程序状态寄存器(sr,对应地址为8)、八个通用寄存器(R0-R7,对应地址为0-7,复位时的值为0),PC寄存器组成。这其中的机器指令、微指令,流水线、周期我都不太能理解,随着不断地学习,慢慢的去剖析这其中的原理。理论联系实际,才能更好地解决问题。

通过这次设计,我感受到计算机的独特魅力,它让一连串的0,1二进制码有了不同的意义,不仅巩固了我的基础知识,也锻炼了我独立思考、编程的基本能力。当然,我深深的知道自己还有许多的不足,我们应该努力去克服这些,在挫折中成长。我们也必须迎合社会的发展,努力去开拓进取,勇于创新,在未来的道路上不断迎接新的挑战,顺应时代的变化,积极投身于理论和实践相结合当中去,不断地练习,应更深一步的体会计算中原理中的知识,最好能用代码去体现,还有思维逻辑的锻炼也是必不可少的,希望自己在今后课程中,不断进步!

六、附录

using System;

using System.IO;

using System.Text;

using System.Text.RegularExpressions;

using System.Windows.Forms;

namespace 计算机原理

{

    public partial class Form1 : Form

    {

        private int i = -1;         //listbox_Jiqi所选中项

        private int mi = 0;         //内存单元被选中的项,即地址

        private int ui = -1;        //指令周期

        private int q = 0;

        private bool all = false;

        private string asmIns;      //提取的指令

        private string PCbaoliu;

        private string[] insSplits; //指令分割

        private string result;

        private enum singleIns

        {

            INC = 1,

            DEC,

            NEG

        }

        //BCD码,就bai是二进制与十进制的转换码du。在计算机中都是2进制zhi来保存数据,因此要把一个10进制数据转换成dao2进制,

        //才能保存在计算机中。但是10进制跟2进制之间转换很麻烦。而BCD吗就是解决这个问题的。BCD码就是把10进制数的每1位都用4位的二进制表示,如:28的BCD码是0010

        private void Form1_Load_1(object sender, EventArgs e)//对窗体界面进行初始化

        {

            textBox_H.Text = "0";

            textBox_S.Text = "0";

            textBox_V.Text = "0";

            textBox_C.Text = "0";

            textBox_N.Text = "0";

            textBox_Z.Text = "0";

            textBox_R0.Text = "00";

            textBox_R1.Text = "00";

            textBox_R2.Text = "00";

            textBox_R3.Text = "00";

            textBox_R4.Text = "00";

            textBox_R5.Text = "00";

            textBox_R6.Text = "00";

            textBox_R7.Text = "00";

            textBox_PC.Text = "0020";

            textBox_BUS.Text = "0000";

            textBox_SR.Text = "00";

            textBox_DR.Text = "00";

            textBox_TEMP.Text = "0000";

            textBox_MAR.Text = "0000";

            textBox_MDR.Text = "0000";

            textBox_IR.Text = "0000";

            textBox_LA.Text = "00";//设置一个初始状态

            for (int j = 0; j < 256; j++)//将256个内存空间附上编号

            {

                char addrHigh = BCDToHex(decToBCD(j / 16));

                char addrLow = BCDToHex(decToBCD(j % 16));

                listBox_Neicun.Items.Add("00" + addrHigh + addrLow + ":" + "0F");

            }

            listBox_Zhiling.Items.Add("FT");    //取指令

            listBox_Zhiling.Items.Add("ST");    //取源操作数

            listBox_Zhiling.Items.Add("DT");    //取目的操作数

            listBox_Zhiling.Items.Add("ET");    //执行指令

        }

        private string hexToBCD(char ch)//将十六进制数转换为BCD码

        {

            string BCD = "";

            switch (ch)

            {

                case '0': BCD = "0000"; break;

                case '1': BCD = "0001"; break;

                case '2': BCD = "0010"; break;

                case '3': BCD = "0011"; break;

                case '4': BCD = "0100"; break;

                case '5': BCD = "0101"; break;

                case '6': BCD = "0110"; break;

                case '7': BCD = "0111"; break;

                case '8': BCD = "1000"; break;

                case '9': BCD = "1001"; break;

                case 'A':

                case 'a': BCD = "1010"; break;

                case 'B':

                case 'b': BCD = "1011"; break;

                case 'C':

                case 'c': BCD = "1100"; break;

                case 'D':

                case 'd': BCD = "1101"; break;

                case 'E':

                case 'e': BCD = "1110"; break;

                case 'F':

                case 'f': BCD = "1111"; break;

            }

            return BCD;

        }

        private char BCDToHex(string BCD)//将BCD码转换为16进制数

        {

            char hex = '\0';

            switch (BCD)

            {

                case "0000": hex = '0'; break;

                case "0001": hex = '1'; break;

                case "0010": hex = '2'; break;

                case "0011": hex = '3'; break;

                case "0100": hex = '4'; break;

                case "0101": hex = '5'; break;

                case "0110": hex = '6'; break;

                case "0111": hex = '7'; break;

                case "1000": hex = '8'; break;

                case "1001": hex = '9'; break;

                case "1010": hex = 'A'; break;

                case "1011": hex = 'B'; break;

                case "1100": hex = 'C'; break;

                case "1101": hex = 'D'; break;

                case "1110": hex = 'E'; break;

                case "1111": hex = 'F'; break;

            }

            return hex;

        }

        private int BCDToDec(string BCD)//将BCD码转换为10进制数

        {

            int dec = 0;

            switch (BCD)

            {

                case "0000": dec = 0; break;

                case "0001": dec = 1; break;

                case "0010": dec = 2; break;

                case "0011": dec = 3; break;

                case "0100": dec = 4; break;

                case "0101": dec = 5; break;

                case "0110": dec = 6; break;

                case "0111": dec = 7; break;

                case "1000": dec = 8; break;

                case "1001": dec = 9; break;

                case "1010": dec = 10; break;

                case "1011": dec = 11; break;

                case "1100": dec = 12; break;

                case "1101": dec = 13; break;

                case "1110": dec = 14; break;

                case "1111": dec = 15; break;

            }

            return dec;

        }

        private string decToBCD(int dec)//将10进制数转换为BCD码

        {

            string BCD = "";

            switch (dec)

            {

                case 0: BCD = "0000"; break;

                case 1: BCD = "0001"; break;

                case 2: BCD = "0010"; break;

                case 3: BCD = "0011"; break;

                case 4: BCD = "0100"; break;

                case 5: BCD = "0101"; break;

                case 6: BCD = "0110"; break;

                case 7: BCD = "0111"; break;

                case 8: BCD = "1000"; break;

                case 9: BCD = "1001"; break;

                case 10: BCD = "1010"; break;

                case 11: BCD = "1011"; break;

                case 12: BCD = "1100"; break;

                case 13: BCD = "1101"; break;

                case 14: BCD = "1110"; break;

                case 15: BCD = "1111"; break;

            }

            return BCD;

        }

        private void isOverflow(ref int high, ref int low) //判断是否上溢并针对上溢进行操作,参数表示运算结果

        {

            if (low > 15)    //低4位1111再加1会产生向高4位的进位

            {

                textBox_H.Text = "1";   //H寄存器置1,H:半进位标志:即低4位是否向高4位进位或借位,如果有则为1,否则,为0

                low %= 16;

                high++;      //高位+1

                if (high > 15)       //高4位1111再加1会导致结果溢出

                {

                    textBox_C.Text = "1";   //C寄存器置1,C:无符号数溢出标志位

                    high %= 16;

                }

                else

                {

                    textBox_C.Text = "0";

                }

            }

            else if (high > 15)       //高4位1111再加1会导致结果溢出

            {

                textBox_C.Text = "1";   //C寄存器置1

                high %= 16;

            }

            else

            {

                textBox_H.Text = "0";

                textBox_C.Text = "0";

            }

        }

        private void isUnderflow(ref int high, ref int low)//判断是否下溢并针对下溢进行操作,参数表示运算结果

        {

            if (low < 0)

            {

                textBox_H.Text = "1";//H:半进位标志:即低4位是否向高4位进位或借位,如果有则为1,否则,为0

                low = (16 + low) % 16;

                high--;

                if (high < 0)

                {

                    textBox_C.Text = "1";//C:无符号数溢出标志位

                    high = (16 + high) % 16;

                }

                else

                {

                    textBox_C.Text = "0";

                }

            }

            else if (high < 0)

            {

                textBox_C.Text = "1";

                high = (16 + high) % 16;

            }

            else

            {

                textBox_H.Text = "0";

                textBox_C.Text = "0";

            }

        }

        private void isZero(int high, int low)//判断零标志位状态,参数表示运算结果

        {

            if (low == 0 && high == 0)

            {

                textBox_Z.Text = "1";//Z:0标志位:若运算结果是0,则为1;否则,为0

            }

            else

            {

                textBox_Z.Text = "0";

            }

        }

        private string selfIncrease(string hexNum, bool isPC)//完成寄存器内操作数自加操作以及pc指令自增

        {

            string highBCD = hexToBCD(hexNum[hexNum.Length - 2]);      //高4位BCD 将16进制数转换成BCD码

            string lowBCD = hexToBCD(hexNum[hexNum.Length - 1]);       //低4位BCD

            int highDec = BCDToDec(highBCD);//将BCD码转换成10进制数

            int lowDec = BCDToDec(lowBCD);

            lowDec = isPC ? lowDec + 2 : lowDec + 1;//

            isOverflow(ref highDec, ref lowDec);

            isZero(highDec, lowDec);        //判断运算结果是否为0

            string newHighBCD = decToBCD(highDec);//将10进制数转换成BCD码

            string newLowBCD = decToBCD(lowDec);

            string newHexNum = "";

            if (isPC)

            {

                newHexNum = "00" + BCDToHex(newHighBCD).ToString() + BCDToHex(newLowBCD).ToString();//BCD转16进制

            }

            else

            {

                newHexNum = BCDToHex(newHighBCD).ToString() + BCDToHex(newLowBCD).ToString();

            }

            return newHexNum;

        }

        private string selfDecrease(string hexNum)//完成寄存器内操作数自减操作

        {

            string highBCD = hexToBCD(hexNum[0]);      //高4位BCD 将16进制转换成BCD码

            string lowBCD = hexToBCD(hexNum[1]);       //低4位BCD

            int highDec = BCDToDec(highBCD);//将BCD码转换成10进制

            int lowDec = BCDToDec(lowBCD);

            lowDec--;

            isUnderflow(ref highDec, ref lowDec);

            isZero(highDec, lowDec);

            string newHighBCD = decToBCD(highDec);//将10进制转换成BCD码

            string newLowBCD = decToBCD(lowDec);

            string newHexNum = BCDToHex(newHighBCD).ToString() + BCDToHex(newLowBCD).ToString();

            return newHexNum;

        }

        private string negComplement(string hexNum)//完成寄存器内操作数求补码操作

        {

            string highBCD = hexToBCD(hexNum[0]);      //高4位BCD 将16进制转换成BCD码

            string lowBCD = hexToBCD(hexNum[1]);       //低4位BCD

            int highDec = BCDToDec(highBCD);//将BCD码转换成10进制数

            int lowDec = BCDToDec(lowBCD);

            highDec = 15 - highDec;//高位转补码过程

            lowDec = (15 - lowDec) + 1;//低位转补码过程

            isOverflow(ref highDec, ref lowDec);

            isZero(highDec, lowDec);

            string newHighBCD = decToBCD(highDec);//将10进制数转换成BCD码

            string newLowBCD = decToBCD(lowDec);

            string newHexNum = BCDToHex(newHighBCD).ToString() + BCDToHex(newLowBCD).ToString();//将BCD码转换成16进制

            return newHexNum;

        }

        private string addMeth(string dstHexNum, string srcHexNum) // 加操作

        {

            string dstHighBCD = hexToBCD(dstHexNum[0]);//将16进制数转换成BCD码

            string dstLowBCD = hexToBCD(dstHexNum[1]);

            int dstHighDec = BCDToDec(dstHighBCD);//将BCD码转换成10进制数

            int dstLowDec = BCDToDec(dstLowBCD);

            //对另一个加数的操作

            string srcHighBCD = hexToBCD(srcHexNum[0]);//将16进制数转换成BCD码

            string srcLowBCD = hexToBCD(srcHexNum[1]);

            int srcHighDec = BCDToDec(srcHighBCD);//将BCD码转换成10进制数

            int srcLowDec = BCDToDec(srcLowBCD);

            nuD_Symbol.Text = "+";

            nuD_Zhenzhi1.Value = (dstHighDec * 16 + dstLowDec) % 127;//转换为真值

            nuD_Zhenzhi2.Value = (srcHighDec * 16 + srcLowDec) % 127;

            string sum = result;

            int sumLow = BCDToDec(sum.Substring(4, 4));

            int sumHigh = BCDToDec(sum.Substring(0, 4));

            int sumshi = sumLow * 16 + sumHigh;

            isOverflow(ref sumHigh, ref sumLow);

            isZero(sumHigh, sumLow);

            string sumHighBCD = decToBCD(sumHigh);

            string sumLowBCD = decToBCD(sumLow);//将10进制转换成BCD码

            string sumHexNum = BCDToHex(sumHighBCD).ToString() + BCDToHex(sumLowBCD).ToString();//将BCD码转换成16进制

            return sumHexNum;

        }

        private string whichRegCode(string regExpr)//获取被操作的寄存器的机器码

        {

            Regex reg = new Regex("(R[0-9]|Z)");    //Regex表示不可变的正则表达式,寄存器对应的正则表达式

            string register = "";               //目标寄存器

            Match match = reg.Match(regExpr);//Match表示单个正则表达式匹配的结果,通过传过来的汇编指令进行匹配

                                             //匹配相应的寄存器

            if (match.ToString() == "R0")

            {

                register = "000";

            }

            else if (match.ToString() == "R1")

            {

                register = "001";

            }

            else if (match.ToString() == "R2")

            {

                register = "010";

            }

            else if (match.ToString() == "R3")

            {

                register = "011";

            }

            else if (match.ToString() == "R4")

            {

                register = "100";

            }

            else if (match.ToString() == "R5")

            {

                register = "101";

            }

            else if (match.ToString() == "R6")

            {

                register = "110";

            }

            else if (match.ToString() == "R7")

            {

                register = "111";

            }

            else if (match.ToString() == "Z")

            {

                register = "111";

            }

            return register;

        }

        private string whichMethodCode(string regExpr) // 获取寻址方式,寻址方式分为5种,分别对应不同的机器码

        {

            Regex regDirAddr = new Regex("^R[0-7]$");               //寄存器寻址

            Regex regIndirAddr = new Regex("^\\(R[0-7]\\)$");       //寄存器间址

            Regex selfIncRegIndirAddr = new Regex("^\\(R[0-7]\\)\\+$"); //自增型寄存器间址

            Regex selfIncRegDoubleIndirAddr = new Regex("^@\\(R[0-7]\\)\\+$"); //自增型双间址

            Regex indexAddr = new Regex("^X\\(R[0-7]\\)$");         //变址寻址

            string method = "";

            if (regDirAddr.IsMatch(regExpr))

            {

                method = " 000";

            }

            else if (regIndirAddr.IsMatch(regExpr))

            {

                method = " 001";

            }

            else if (selfIncRegIndirAddr.IsMatch(regExpr))

            {

                method = " 010";

            }

            else if (selfIncRegDoubleIndirAddr.IsMatch(regExpr))

            {

                method = " 011";

            }

            else if (indexAddr.IsMatch(regExpr))

            {

                method = " 100";

            }

            return method;

        }

        private string getRegOprand(string reg)//获取目标寄存器内的操作数

        {

            string oprand = "";

            if (reg == "R0" || reg == "00" )

                oprand = textBox_R0.Text;

            if (reg == "R1" || reg == "01")

                oprand = textBox_R1.Text;

            if (reg == "R2" || reg == "02")

                oprand = textBox_R2.Text;

            if (reg == "R3" || reg == "03")

                oprand = textBox_R3.Text;

            if (reg == "R4" || reg == "04")

                oprand = textBox_R4.Text;

            if (reg == "R5" || reg == "05")

                oprand = textBox_R5.Text;

            if (reg == "R6" || reg == "06")

                oprand = textBox_R6.Text;

            if (reg == "R7" || reg == "07")

                oprand = textBox_R7.Text;

            if (reg == "(R0)")

            {

                int Neicun = BCDToDec(hexToBCD(textBox_R0.Text.Substring(0, 1).ToCharArray()[0])) * 16 + BCDToDec(hexToBCD(textBox_R0.Text.Substring(1, 1).ToCharArray()[0]));

                oprand = listBox_Neicun.Items[Neicun].ToString();

            }

            if (reg == "(R1)")

            {

                int Neicun = BCDToDec(hexToBCD(textBox_R1.Text.Substring(0, 1).ToCharArray()[0])) * 16 + BCDToDec(hexToBCD(textBox_R1.Text.Substring(1, 1).ToCharArray()[0]));

                oprand = listBox_Neicun.Items[Neicun].ToString();

            }

            if (reg == "(R2)")

            {

                int Neicun = BCDToDec(hexToBCD(textBox_R2.Text.Substring(0, 1).ToCharArray()[0])) * 16 + BCDToDec(hexToBCD(textBox_R2.Text.Substring(1, 1).ToCharArray()[0]));

                oprand = listBox_Neicun.Items[Neicun].ToString();

            }

            if (reg == "(R3)")

            {

                int Neicun = BCDToDec(hexToBCD(textBox_R3.Text.Substring(0, 1).ToCharArray()[0])) * 16 + BCDToDec(hexToBCD(textBox_R3.Text.Substring(1, 1).ToCharArray()[0]));

                oprand = listBox_Neicun.Items[Neicun].ToString();

            }

            if (reg == "(R4)")

            {

                int Neicun = BCDToDec(hexToBCD(textBox_R4.Text.Substring(0, 1).ToCharArray()[0])) * 16 + BCDToDec(hexToBCD(textBox_R4.Text.Substring(1, 1).ToCharArray()[0]));

                oprand = listBox_Neicun.Items[Neicun].ToString();

            }

            if (reg == "(R6)")

            {

                int Neicun = BCDToDec(hexToBCD(textBox_R6.Text.Substring(0, 1).ToCharArray()[0])) * 16 + BCDToDec(hexToBCD(textBox_R6.Text.Substring(1, 1).ToCharArray()[0]));

                oprand = listBox_Neicun.Items[Neicun].ToString();

            }

            if (reg == "(R7)")

            {

                int Neicun = BCDToDec(hexToBCD(textBox_R7.Text.Substring(0, 1).ToCharArray()[0])) * 16 + BCDToDec(hexToBCD(textBox_R7.Text.Substring(1, 1).ToCharArray()[0]));

                oprand = listBox_Neicun.Items[Neicun].ToString();

            }

            return oprand;

        }

        private void getValue(string reg, string value)//向寄存器里写内容

        {

            if (reg == "R0" || reg == "00")

            {

                textBox_R0.Text = value;

            }

            if (reg == "R1" || reg == "01")

            {

                textBox_R1.Text = value;

            }

            if (reg == "R2" || reg == "02")

            {

                textBox_R2.Text = value;

            }

            if (reg == "R3" || reg == "03")

            {

                textBox_R3.Text = value;

            }

            if (reg == "R4" || reg == "04")

            {

                textBox_R4.Text = value;

            }

            if (reg == "R5" || reg == "05")

            {

                textBox_R5.Text = value;

            }

            if (reg == "R6" || reg == "06")

            {

                textBox_R6.Text = value;

            }

            if (reg == "R7" || reg == "07")

            {

                textBox_R7.Text = value;

            }

            if (reg =="(R0)" )

            {

                int Neicun = BCDToDec(hexToBCD(textBox_R0.Text.Substring(0, 1).ToCharArray()[0])) * 16 + BCDToDec(hexToBCD(textBox_R0.Text.Substring(1, 1).ToCharArray()[0]));

                value = listBox_Neicun.Items[Neicun].ToString().Substring(0,5) + value;

                listBox_Neicun.Items.RemoveAt(Neicun);

                listBox_Neicun.Items.Insert(Neicun, value);

            }

            if (reg == "(R1)")

            {

                int Neicun = BCDToDec(hexToBCD(textBox_R1.Text.Substring(0, 1).ToCharArray()[0])) * 16 + BCDToDec(hexToBCD(textBox_R1.Text.Substring(1, 1).ToCharArray()[0]));

                value = listBox_Neicun.Items[Neicun].ToString().Substring(0, 5) + value;

                listBox_Neicun.Items.RemoveAt(Neicun);

                listBox_Neicun.Items.Insert(Neicun, value);

            }

            if (reg == "(R2)")

            {

                int Neicun = BCDToDec(hexToBCD(textBox_R2.Text.Substring(0, 1).ToCharArray()[0])) * 16 + BCDToDec(hexToBCD(textBox_R2.Text.Substring(1, 1).ToCharArray()[0]));

                value = listBox_Neicun.Items[Neicun].ToString().Substring(0, 5) + value;

                listBox_Neicun.Items.RemoveAt(Neicun);

                listBox_Neicun.Items.Insert(Neicun, value);

            }

            if (reg == "(R3)")

            {

                int Neicun = BCDToDec(hexToBCD(textBox_R3.Text.Substring(0, 1).ToCharArray()[0])) * 16 + BCDToDec(hexToBCD(textBox_R3.Text.Substring(1, 1).ToCharArray()[0]));

                value = listBox_Neicun.Items[Neicun].ToString().Substring(0, 5) + value;

                listBox_Neicun.Items.RemoveAt(Neicun);

                listBox_Neicun.Items.Insert(Neicun, value);

            }

            if (reg == "(R4)")

            {

                int Neicun = BCDToDec(hexToBCD(textBox_R4.Text.Substring(0, 1).ToCharArray()[0])) * 16 + BCDToDec(hexToBCD(textBox_R4.Text.Substring(1, 1).ToCharArray()[0]));

                value = listBox_Neicun.Items[Neicun].ToString().Substring(0, 5) + value;

                listBox_Neicun.Items.RemoveAt(Neicun);

                listBox_Neicun.Items.Insert(Neicun, value);

            }

            if (reg == "(R5)")

            {

                int Neicun = BCDToDec(hexToBCD(textBox_R5.Text.Substring(0, 1).ToCharArray()[0])) * 16 + BCDToDec(hexToBCD(textBox_R5.Text.Substring(1, 1).ToCharArray()[0]));

                value = listBox_Neicun.Items[Neicun].ToString().Substring(0, 5) + value;

                listBox_Neicun.Items.RemoveAt(Neicun);

                listBox_Neicun.Items.Insert(Neicun, value);

            }

            if (reg == "(R6)")

            {

                int Neicun = BCDToDec(hexToBCD(textBox_R6.Text.Substring(0, 1).ToCharArray()[0])) * 16 + BCDToDec(hexToBCD(textBox_R6.Text.Substring(1, 1).ToCharArray()[0]));

                value = listBox_Neicun.Items[Neicun].ToString().Substring(0, 5) + value;

                listBox_Neicun.Items.RemoveAt(Neicun);

                listBox_Neicun.Items.Insert(Neicun, value);

            }

            if (reg == "(R7)")

            {

                int Neicun = BCDToDec(hexToBCD(textBox_R7.Text.Substring(0, 1).ToCharArray()[0])) * 16 + BCDToDec(hexToBCD(textBox_R7.Text.Substring(1, 1).ToCharArray()[0]));

                value = listBox_Neicun.Items[Neicun].ToString().Substring(0, 5) + value;

                listBox_Neicun.Items.RemoveAt(Neicun);

                listBox_Neicun.Items.Insert(Neicun, value);

            }

        }

        private string[] visitMemory(string hexNum)// 访问数据寄存器

        {

            string addrBCDHigh = hexToBCD(hexNum[0]);   //内存单元高4位BCD码

            string addrBCDLow = hexToBCD(hexNum[1]);    //内存单元低4位BCD码

            int addrDecHigh = BCDToDec(addrBCDHigh);

            int addrDecLow = BCDToDec(addrBCDLow);

            mi = addrDecHigh * 16 + addrDecLow;

            listBox_Neicun.SelectedIndex = mi;

            string selectedStr = listBox_Neicun.SelectedItem.ToString();

            string[] keyAndValue = selectedStr.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);

            return keyAndValue;

        }

        private void locateMemoryRegValue(string reg)//定位寄存器对应主存单元

        {

            if (reg == "R0")

            {

                mi = 0;

            }

            else if (reg == "R1")

            {

                mi = 1;

            }

            else if (reg == "R2")

            {

                mi = 2;

            }

            else if (reg == "R3")

            {

                mi = 3;

            }

            else if (reg == "R4")

            {

                mi = 4;

            }

            else if (reg == "R5")

            {

                mi = 5;

            }

            else if (reg == "R6")

            {

                mi = 6;

            }

            else if (reg == "R7")

            {

                mi = 7;

            }

        }

        private void writeMemory(string reg, string value)//向寄存器共用内存单元里写数据

        {

            string RX = getRegOprand(reg);

            string RXLow = hexToBCD(RX[1]);

            string RXHigh = hexToBCD(RX[0]);

            int intRXLow = BCDToDec(RXLow);

            int intRXHigh = BCDToDec(RXHigh);

            int intRX = (intRXHigh * 16) + intRXLow;

            listBox_Neicun.Items[intRX] = "00" + RX + ":" + value;

        }

你可能感兴趣的:(visual,studio,c#,51单片机)