C++程序设计(Massey机器模拟)

Assigment2复盘

写在开始:

1.刚开始时有大致思路,没有头绪。沉淀大概一个星期后,又看到别人代码思路自己试着理解形成大致思路。

2.将思路要求等付诸纸面,看一看自己需要解决那些问题,将一个大问题进行肢解。直到肢解到自己可以解决的大小为止。

3.每次重构自己的Shit Mountion都是在理顺思路和逻辑。重构未必是坏事。

程序要求:

Write a C++ program that simulates the MASSEY machine. The program must receive input in the form of a text file consisting of MASSEY machine code instructions. Your program then simulates the machine running, i.e. it works through the machine code instructions (in the correct sequence) changing values of registers and memory locations as required. You must design appropriate output that assists a machine code programmer to see what is going on with the machine code instructions. You shoulddisplay items such as program counter, instructions register, values of recently changed registers, and values of recently changed memory locations.
译:
编写一个模拟MASSEY机器的C++程序。程序必须接收由Massey机器代码指令组成的文本文件形式 的输入。然后,您的程序将模拟机器的运行,即。它通过机器代码指令(按正确的顺序)根据需 要改变寄存器和内存位置的值。您必须设计适当的输出,帮助机器代码程序员查看机器代码指令 发生了什么。您应该显示诸如程序计数器、指令寄存器、最近更改的寄存器的值和最近更改的内 存位置的值等项目。

Section A - input

The input to your program is a single text file containing a MASSEY machine code program.For example, here is a typical input file where each line is a machine code instruction:
1102
1203
6012
40FF
E000
Notes about the input:

  1. The programmer using the simulation can give the file whatever name they like. It is best to read
    in the file name when you start. A typical file name would be “prog1.txt”.
  2. Each line of the file is one machine code instruction. There is no other text in the file.
  3. Make several (at least five) different files, each with a different machine code program. Test your
    program on a variety of machine code programs.
  4. Do not attempt to check for invalid input. Assume every program contains correct machine code
    instructions although a program may have logic errors, e.g. instructions in the incorrect order.

译:
程序的输入是一个包含Massey机器代码程序的单个文本文件。例如,这里是一个典型的输入文件,其中每一行都是一个机器代码指令:
1102
1203
6012
40FF
E000
注意:
1.使用该模拟的程序员可以给该文件提供任何他们喜欢的名称。最好在启动时读取文件名。一个典型的文件名应该是“prog1”。txt" .2.该文件的每一行都是一条机器代码指令。该文件中没有其他文本。 3.制作几个(至少五个)不同的文件,每个文件都有不同的机器代码程序。在各种机器代码程序 上测试您的程序。 4.不要尝试检查是否有无效的输入。假设每个程序都包含正确的机器代码指令,尽管一个程序可能有逻辑错误,例如指令的顺序不正确。

Section B – program design

Your program must use the following global variables:
int memory[256];
int reg[16]; // note: “register” is a reserved word
int pc, ir;
The array “memory” represents the memory of the MASSEY machine.
The array “registers” represents the registers of the MASSEY machine.
The variable “pc” is the Program Counter and “ir” is the instruction register.
The basic algorithm for your program is:
• read instructions from the file and load them into memory
• run through the instructions and execute each instruction correctly
Notes about the program design:
5. Study the MASSEY machine code instructions in the notes.
6. Ensure that your program correctly executes and valid machine code instruction.
7. You do not have to execute instruction 5 (floating point addition) – ignore instruction 5.
8. Do not check for invalid instructions. Only deal with valid instructions.
9. You must have at least two functions in your program.
10. Test extensively. Ensure that you have tested every instruction (except 5). Use machine code
programs from the notes as test data.

译:
您的程序必须使用以下全局变量:
int memory[256];
int reg[16];//注意:“寄存器”是一个保留的词
int pc, ir;
数组“内存”表示Massey机器的内存。 数组“寄存器”表示Massey机器的寄存器。 变量“pc”是程序计数器,“ir”是指令寄存器。

您的程序的基本算法是: 从文件中读取指令,并将其加载到内存中 运行这些指令并正确地执行每个指令 记下 关于 那 程序 设计 5.研究注释中的MASSEY机器代码说明。 6.确保您的程序正确地执行和有效的机器代码指令。 7.您不必执行指令5(浮点加法)-忽略指令5。 8.不要检查是否无效的指令。只处理有效的指令。 9.您的程序中必须至少有两个函数。 10.测试广泛。确保您已经测试了每条指令(5条除外)。使用注释中的机器代码程序作为测试数据。

Section C - output

The output must meet the following requirements:

  • display the full program (showing the memory locations) before executing the program
  • identify the important items to display during execution of the instructions
  • display one line for every machine code instruction (showing any changes)
    For example, your display could look like this:
    Enter the file name of the MASSEY machine code: program1.txt
    Memory[0] = 1102
    Memory[1] = 1203
    Memory[2] = 6012
    Memory[3] = 40FF
    Memory[4] = E000
    1102 R1 = 0002 PC = 1
    1203 R2 = 0003 PC = 2
    6012 R0 = 0005 PC = 3
    40FF Memory[FF] = 0005 PC = 4
    Halt
    Notes about the output:
  1. Display one line of output for each machine code instruction – just after it has been executed.
  2. On each line, display the current instruction and the Program Counter (which is loaded with the address of the next instruction).
  3. On each line, display any registers that have changed. E.g. the first instruction above loads R1 so the value in R1 is displayed.
  4. On each line, display any memory locations that have changed. E.g. the fourth instruction above loads a value into memory location FF so the value in memory[FF] is displayed.

译:
输出值必须满足以下要求: 在执行程序之前显示完整的程序(显示内存位置) 识别在执行指令期间要显示的重要项目 -为每条机器代码指令显示一行(显示任何更改) 例如,您的显示器可能是这样的: 输入MASSEY机器代码的文件名: program1.txt 记下 关于 那 产量 11.为每个机器代码指令显示一行输出-就在它被执行之后。 12.在每一行上,显示当前指令和程序计数器(加载下一条指令的地址)。 13.在每一行上,显示所有已更改的所有寄存器。E.g.上面的第一个指令加载R1,因此显示R1中 的值。 14.在每一行上,显示任何已更改的内存位置。E.g.上面的第四条指令将值加载到内存位置FF, 从而显示内存位置FF中的值。

以下是机器指令所代表含义:

1RXY Load register R with the value XY.

e.g. 1213 means load register R2 with the hexadecimal number 13 (19 in decimal).

20RS Load register R with the number in register S.

e.g. 20A7 means load register R10 with the number in register R7.

3RXY Load register R with the number in the memory location at address XY.

e.g. 34AB means load register R4 with the contents from memory location AB

4RXY Store the number in register R in the memory location at address XY.

e.g. 45B1 means store the contents of register R5 in the memory location B1

5RST Add the numbers in registers S and T and load the result into register R.

Note: this is floating point addition.
e.g. 534E means add the numbers in R4 and R14 and load the result into R3.

6RST Add the numbers in registers S and T and load the result into register R.

Note: this is integer addition using 2’s complement arithmetic.
e.g. 6823 means add the contents of R2 and R3 and load the result into R8.

70R0 Negate register R. (Carry out complement and add 1 – in effect, multiply R with -1)

e.g. 70A0 means multiply the number in R10 by -1.

8R0X Shift the number in register R to the right X times.

e.g. 8403 means that the number in R4 must be shifted 3 bits to the right.

9R0X Shift the number in register R to the left X times.

e.g. 9602 means that the number in R6 must be shifted 2 bits to the left.

ARST AND the numbers in registers S and T and load the result into register R.

e.g. A045 means AND the numbers in R4 and R5 and load the result into R0.

BRST OR the numbers in registers S and T and load the result into register R.

e.g. BC74 means OR the numbers in R7 and R4 and load the result into R12.

CRST XOR the numbers in registers S and T and load the result into register R.

e.g. C5F3 means XOR the numbers in R15 and R3 and load the result into R5.

DRXY Jump to the instruction at address XY if the value in register R is equal
to the value in register R0.

e.g. D43C means the following:
(a) compare the contents of R4 with R0.
(b) if they are equal load 3C into the program counter.

E000 Halt

题主遇到的问题:

一.文件问题:1.对指定名称文件进行读取 2. 根据文件内容选择读取方式 3.对文件操作函数不熟悉

二.函数问题:1.函数如何操作函数之外的变量 2.引用调用不可对数组进行操作?

三.流输入输出格式化问题

四.计算机操作的实质问题、二进制、十进制、十六进制的操作、逻辑操作问题

五.官方文档的阅读能力问题

Show Something you want

能动手就别bb

#include<iostream>
#include<string>
#include<fstream>
using namespace std;
//-----------Must to be used Var------------------
int memory[256];
int reg[16];
int pc , ir;
//--------------Own var---------------------------
int CodeNum;//the number of MasseyCode
int OperateNum,SecondNum,ThirdNum,FourthNum;
ifstream file;
//--------------Some Function---------------------
//这个函数就是以4位宽度输出不足位数用0补齐,但只对最近的一个cout有作用,题主犯懒所以写个函数调用它俩
void Output_with0_in4()
{
    cout.width(4);
    cout.fill('0');
}
//将文本中的机器码写入memory,并按格式输出
void Loading()
{
    for(int i = 0; i <256; i++){
        file>>hex>>memory[i];
        cout<<"Memory["<<i<<"] = ";
        Output_with0_in4();//NOTE!OutPut also should be in Patten
        cout<<hex<<uppercase<<memory[i]<<endl;
        CodeNum = i + 1;
        if(file.eof()){
            break;
        }
    }
    cout<<endl;
}
//得到机器指令的每一位数字,注意这里用到的十六进制逻辑操作方法
void GetEveryPostionNumber(int Messycode)
{
    OperateNum  = Messycode >> 12;
    SecondNum = (Messycode & 0X0f00) >> 8;
    ThirdNum = (Messycode & 0x00f0) >> 4;
    FourthNum = Messycode & 0X000f;
}
//输出函数
void Display(int RegChangedPostion,int RegChangedValue,int MemChangedPostion,int MemChangedValue,int choice)
{
    if(choice > 0)
    {
        cout<<"R";
        cout<<hex<<uppercase<<RegChangedPostion<<" = ";
        Output_with0_in4();
        cout<<hex<<uppercase<<RegChangedValue<<"    ";
    }
    else
    {
        cout<<"Memory[";
        cout<<hex<<uppercase<<MemChangedPostion<<"] = ";
        Output_with0_in4();
        cout<<hex<<uppercase<<MemChangedValue<<"    ";
    }
}
int main(){
    //--------------------------------------------
    //printf all the MasseyCode in Memory
    string FileName;
    cout<<"Enter the file name of the MASSEY machine code: ";
    cin>>FileName;
    cout<<endl;
    file.open(FileName.c_str(),ios::in);
    if(!file.is_open()){
        cout<<"File Open Was Wrong!"<<endl;
        return 0;
    }
    Loading();
    //---------------------------------------------
    //Execute the MasseyCoed in ir
    for(int i = 0; i < CodeNum ; i++)
    {   
        //-----------------------------------------
        //Load ir with MeassyCode in Memory
        labs:
        ir = memory[i];  
        //printf currently executed MeassyCode
        if(ir == 0xE000)
        {
            cout<<"Halt";
        }
        else
        {
            cout<<ir<<"    ";
        }
        //--------------------Executing----------------------------
        GetEveryPostionNumber(ir);
        switch (OperateNum)
        {
            case 1:
                reg[SecondNum] = ThirdNum * 16 + FourthNum;
                Display(SecondNum,reg[SecondNum],0,0,1);
                break;
            case 2:
                reg[ThirdNum] = reg[FourthNum];
                Display(ThirdNum,reg[ThirdNum],0,0,1);
                break;
            case 3:
                reg[SecondNum] = memory[ThirdNum * 16 + FourthNum];
                Display(SecondNum,reg[SecondNum],0,0,1);
                break;
            case 4:
                memory[ThirdNum * 16 + FourthNum] = reg[SecondNum];
                Display(0,0,(ThirdNum *16 + FourthNum),memory[ThirdNum * 16 + FourthNum],-1);
                break;
            case 5:
                //Needn't to be considered
            case 6:
                reg[SecondNum] = reg[ThirdNum] + reg[FourthNum];
                Display(SecondNum,reg[SecondNum],0,0,1);
                break;
            case 7:
                reg[ThirdNum] = -1 * reg[ThirdNum];
                Display(ThirdNum,reg[ThirdNum],0,0,1);
                break;
            case 8:
                reg[SecondNum] = reg[SecondNum] >> FourthNum;
                Display(SecondNum,reg[SecondNum],0,0,1);
                break;
            case 9:
                reg[SecondNum] = reg[SecondNum] << FourthNum;
                Display(SecondNum,reg[SecondNum],0,0,1);
                break;
            case 10:
                reg[SecondNum] = reg[ThirdNum] & reg[FourthNum];
                Display(SecondNum,reg[SecondNum],0,0,1);
                break;
            case 11:
                reg[SecondNum] = reg[ThirdNum] | reg[FourthNum];
                Display(SecondNum,reg[SecondNum],0,0,1);
                break;
            case 12:
                reg[SecondNum] = reg[ThirdNum] ^ reg[FourthNum];
                Display(SecondNum,reg[SecondNum],0,0,1);
                break;
            case 13:
            //特殊处理pc
                if(reg[SecondNum] == reg[0])
                {
                    cout<<"             "<<"PC = ";
                    i = ThirdNum * 16 + FourthNum;
                    cout<< i <<endl;
                    goto labs;
                }
                else
                {
                    cout<<"             ";
                }
                break;
            case 14:
                return 0;//Note!when it equal E menas over.
        }
        //---------------------Output PC-----------------------------------
        //注意pc的处理,跳转和不跳转分开处理,还是要理解pc的实质:指向将要处理的指令地址
        pc = i + 1 ;
        if( ir != 0xE000 ){
            cout<<"PC = "<<pc<<endl;
        }
    }
}
//
//                       .::::.
//                     .::::::::.
//                    :::::::::::
//                 ..:::::::::::'
//              '::::::::::::'
//                .::::::::::
//           '::::::::::::::..
//                ..::::::::::::.
//              ``::::::::::::::::
//               ::::``:::::::::'        .:::.
//              ::::'   ':::::'       .::::::::.
//            .::::'      ::::     .:::::::'::::.
//           .:::'       :::::  .:::::::::' ':::::.
//          .::'        :::::.:::::::::'      ':::::.
//         .::'         ::::::::::::::'         ``::::.
//     ...:::           ::::::::::::'              ``::.
//    ````':.          ':::::::::'                  ::::..
//                       '.:::::'                    ':'````..

给出几个测试案例:

题干中给出的
//此txt文本文件名称: prog1.txt
1102
1203
6012
40FF
E000

本代码结果:

Enter the file name of the MASSEY machine code: prog1.txt

Memory[0] = 1102
Memory[1] = 1203
Memory[2] = 6012
Memory[3] = 40FF
Memory[4] = E000

1102    R1 = 0002    PC = 1
1203    R2 = 0003    PC = 2
6012    R0 = 0005    PC = 3
40FF    Memory[FF] = 0005    PC = 4
Halt
测试DRXY(题主自测)

案例一:

//此txt文本文件名称: prog7.txt
1012
1112
1212
D105
1312
D208
1412
1512
1612
Enter the file name of the MASSEY machine code: prog7.txt

Memory[0] = 1012
Memory[1] = 1112
Memory[2] = 1212
Memory[3] = D105
Memory[4] = 1312
Memory[5] = D208
Memory[6] = 1412
Memory[7] = 1512
Memory[8] = 1612

1012    R0 = 0012    PC = 1
1112    R1 = 0012    PC = 2
1212    R2 = 0012    PC = 3
D105                 PC = 5
D208                 PC = 8
1612    R6 = 0012    PC = 9

案例二:

//此txt文本文件名称: prog6.txt
1012
1112
D104
1513
1212
Enter the file name of the MASSEY machine code: prog6.txt

Memory[0] = 1012
Memory[1] = 1112
Memory[2] = D104
Memory[3] = 1513
Memory[4] = 1212

1012    R0 = 0012    PC = 1
1112    R1 = 0012    PC = 2
D104                 PC = 4
1212    R2 = 0012    PC = 5

案例三:

//此txt文本文件名称: prog8.txt
//等价于
/*  i = 9;
    while (i >= 0) {
    i--;
    }
*/
1080
9008
1209
4247
1A01
70A0
3347
A230
D20C
633A
4347
D006
E000
Enter the file name of the MASSEY machine code: prog8.txt

Memory[0] = 1080
Memory[1] = 9008
Memory[2] = 1209
Memory[3] = 4247
Memory[4] = 1A01
Memory[5] = 70A0
Memory[6] = 3347
Memory[7] = A230
Memory[8] = D20C
Memory[9] = 633A
Memory[A] = 4347
Memory[B] = D006
Memory[C] = E000

1080    R0 = 0080    PC = 1
9008    R0 = 8000    PC = 2
1209    R2 = 0009    PC = 3
4247    Memory[47] = 0009    PC = 4
1A01    RA = 0001    PC = 5
70A0    RA = FFFFFFFF    PC = 6
3347    R3 = 0009    PC = 7
A230    R2 = 0000    PC = 8
D20C                 PC = 9
633A    R3 = 0008    PC = A
4347    Memory[47] = 0008    PC = B
D006                 PC = 6
3347    R3 = 0008    PC = 7
A230    R2 = 0000    PC = 8
D20C                 PC = 9
633A    R3 = 0007    PC = A
4347    Memory[47] = 0007    PC = B
D006                 PC = 6
3347    R3 = 0007    PC = 7
A230    R2 = 0000    PC = 8
D20C                 PC = 9
633A    R3 = 0006    PC = A
4347    Memory[47] = 0006    PC = B
D006                 PC = 6
3347    R3 = 0006    PC = 7
A230    R2 = 0000    PC = 8
D20C                 PC = 9
633A    R3 = 0005    PC = A
4347    Memory[47] = 0005    PC = B
D006                 PC = 6
3347    R3 = 0005    PC = 7
A230    R2 = 0000    PC = 8
D20C                 PC = 9
633A    R3 = 0004    PC = A
4347    Memory[47] = 0004    PC = B
D006                 PC = 6
3347    R3 = 0004    PC = 7
A230    R2 = 0000    PC = 8
D20C                 PC = 9
633A    R3 = 0003    PC = A
4347    Memory[47] = 0003    PC = B
D006                 PC = 6
3347    R3 = 0003    PC = 7
A230    R2 = 0000    PC = 8
D20C                 PC = 9
633A    R3 = 0002    PC = A
4347    Memory[47] = 0002    PC = B
D006                 PC = 6
3347    R3 = 0002    PC = 7
A230    R2 = 0000    PC = 8
D20C                 PC = 9
633A    R3 = 0001    PC = A
4347    Memory[47] = 0001    PC = B
D006                 PC = 6
3347    R3 = 0001    PC = 7
A230    R2 = 0000    PC = 8
D20C                 PC = 9
633A    R3 = 0000    PC = A
4347    Memory[47] = 0000    PC = B
D006                 PC = 6
3347    R3 = 0000    PC = 7
A230    R2 = 0000    PC = 8
D20C                 PC = 9
633A    R3 = FFFFFFFF    PC = A
4347    Memory[47] = FFFFFFFF    PC = B
D006                 PC = 6
3347    R3 = FFFFFFFF    PC = 7
A230    R2 = 8000    PC = 8
D20C                 PC = C
Halt

案例四:

//此txt文本文件名称: endlessloop.txt
1012
1112
D100
Enter the file name of the MASSEY machine code: endlessloop.txt

Memory[0] = 1012
Memory[1] = 1112
Memory[2] = D100

1012    R0 = 0012    PC = 1
1112    R1 = 0012    PC = 2
D100                 PC = 0
1012    R0 = 0012    PC = 1
1112    R1 = 0012    PC = 2
D100                 PC = 0
1012    R0 = 0012    PC = 1
1112    R1 = 0012    PC = 2
D100                 PC = 0
1012    R0 = 0012    PC = 1
1112    R1 = 0012    PC = 2
D100                 PC = 0
         ........
         ........
         ........

1012    R0 = 0012    PC = 1
1112    R1 = 0012    PC = 2
D100                 PC = 0
         .........
         .........
其余测试案例均可轻易想到,不再赘述。如有其他本代码不可跑过的测试案例欢迎留言!

写在最后

1.题主曾多次使用goto语句(但单个程序中不超过1次),确实因为能力有限或其他因素,只能想到这样的处理办法,如有其它好方法欢迎留言交流。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值