虚拟计算机,虚拟的语言,用虚拟的语言完成文章中的三个问题

/*7.27b.c*/	
/*继续语言设计*/

/*
构建一台计算机并称其为“Simpletron”。正如它的名字所表示的那样,
它只是一台简单的计算机,但是我们很快就会看到,它的能力还是很
强的。Simpletron唯一能够理解的语言是Simpletron机器语言
(Simpletrom Machine Language,简称SML),它只能够指向采用
SML编写的程序。
simpletron包含一个累加器(accumulator)---用于存放即将被simpletron
处理的信息的特殊的寄存器。在simpletron中处理的所以信息都是以子(word)
为单位。字是一个 有符号的4为十进制数,如:+3364,-1293,+0007,——0001
等。simpletron带有一个容量为100字的存储器(以下简称内存)。这些字可以
通过他们的地址(00,01---99)来访问。

在运行一个SML程序之前,需要将程序加载到内存中。每个SML程序的第一条指针
(或称语句)总是被存放在地址为00的内存单元中。
每一条采用SML编写的指令都是占据内存中的一个字(所以指令也是一个有符号的
4位十进制数)。我们假设SML指令的符号总是正号,但是数据的符号是可正可负
的。simpletron内存中的一个存储单元要么存储一条指令,要么存储一个数据。
要么是展示空闲(和未定义)的。
SML指令的头两个数字是用来表示操作类型的造作码(operation code)。sml
的各种操作码见图7.32

操作码---------------------含义--------------------------------
输入/输出操作
#define READ 10		从中断将一个字读入到内存指定单元中
#define WRITE 11	将内存指定单元中的一个字写到终端上

装入/存回操作
#define LOAD 20		将内存指定单元中的一个字装入累加器
#define STORE 21	从累加器将一个字村回到内存指定单元中
算术运算操作
#define ADD 31		将内存知道抵挡单元中的一个字与累加器中的字相加(结果存到累加器中)
#define SUBTRACT 31	将累加器中的字减去内存指定单元中的一个字(结果存到累加器中)
#define DIVIDE 32	将累加器中字除以内存指定单元中的一个字(结果存在累加器中)
#define MULTIPLY 33	将累加器中的字乘以内存指定单元中的字(结果留在累加器中)
控制转移操作
#define BRANCH 40	转移到内存指定单元
#define BRANCHNEG 41	如果累加器位负数。则转移到内存指定单元
#define BRANCHZERO 42	如果累加器位零,则转移到内存指定单元
#define HALT 43			停机---即程序完成了它的任务

-------------------------------------------------------		
		图7.32 Simpletron机器语言(SML)的操作码

SML指令的后两个数字是操作码(operand),它表示欲操作的数据字所在内存存储单元的地址。
举几个SML程序的列子。下面给出的SML程序从键盘上读取两个数,然后计算并打印它们的和。
--------------------------------------------
例程1	
单元地址		存储的数据		对应的指令
00			+1007			(read a)
01			+1008			(read b)
02			+2007			(load a)
03			+3008			(add b)
04			+2109			(store c)
05			+1109			(write c)
06			+4300			(halt)
07			+0000			(variable a)
08			+0000			(variable b)
09			+0000			(result c)
-------------------------------------------

指令+1007从键盘上读取第一个数并将它存放在地址位07的内存单元(
事先已经被初始化位0)中,指令+1008从键盘上读取第二个数并将它
存放在地址位08的内存单元(实现已经被初始化位0)中,装入指令
+2007将第一个数送入累加器,加法指令3009将第二个数与累加器
中的数相加,并将记过存回累加器,事实上,所有的sml算术指令都将
它们的运算结果保留在累加器中,保存指令+2009将结果存入到地址为
09的内存单元(事先已经被初始化为0)中,读指令+1109将从09单元
读一个数并将其按照有符号的4为十进制数形式大于出来,停机指令
+4300结束程序的运行。


下面给出的SML程序从就按盘上读取两个数,然后比较它们的大小,最后大于其中
较大的那个数,指令+4107是一个条件转移指令,它的用途类似c语言的if语句。
-----------------------------------------------
例程2
单元地址		存储的数据		对应的指令
00			+1009			(read a)
01			+1010			(read b)
02			+2009			(load a)
03			+3110			(subtract b)
04			+4107			(branch negative to 07)
05			+1109			(write a)
06			+4300			(halt)
07			+1110			(write b)
08			+0000			(halt)
09			+0000			(variable a)
10			+0000			(variable b)
11
-------------------------------------------


现在请编写三个SML程序来分别完成一下任务。
a)用一个标记控制循环来从键盘上读入10个正数,然后计算并打印它们的和
b)用一个计数控制循环来从键盘上读入7个数,这些书有的正数也有负数,然后计算并打印它们的和
c)从键盘上读取若干个数,然后比较它们的大小,最后打印其中最大的那个数。
读入的第一个数用来指明将要比较的数据的个数。

另外一篇文章完成这三个问题,这里搭建好运行的环境
文章后面附上,此次练习的答案
*/

#include<stdio.h>
#define SIZE 100
#define FLAG -9999

/*打印内存*/
void printmemory(int m[], int accumulator, int instructionCounter,
	int instructionRegister, int operationCode, int operand);

int errZero(int operand);/*除0错误*/
int errAccumulator(int accumulator);/*累加器溢出错误*/
int erroperandCode(int operationCode);/*操作码错误*/

/*程序从main开始执行*/
int main()
{
	/*打印输出*/
	printf("欢迎来到Simpletron\n");

	/*新建数组memory并初始化*/
	int memory[SIZE] = { 0 };

	/*寄存器值初始化*/
	int accumulator = 0;				//累加器	
	int instructionCounter = 0;			/*内存编号--数组下标*/
	int instructionRegister = 0;		/*'word'*/
	int operationCode = 0;				/*操作码*/
	int operand = 0;					/*位置编号*/
	 

	/*打印内存*/
	printmemory(memory, accumulator, instructionCounter,
		instructionRegister, operationCode, operand);
	printf("\n\n");

	/*将SML程序加载到内存----数组memory*/
	do
	{
		do
		{
			printf("%02d ? +", instructionCounter);
			scanf("%d", &memory[instructionCounter]);
			if (memory[instructionCounter] > 9999 || memory[instructionCounter] < FLAG)
			{
				printf("输入错误,请重新输入!\n");
			}
		} while (memory[instructionCounter] > 9999 || memory[instructionCounter] < FLAG);
		++instructionCounter;
	} while (memory[instructionCounter - 1] != FLAG);

	printf("\n*****程序加载完成*****\n"); 

	/*打印内存*/
	printmemory(memory, accumulator, instructionCounter,
		instructionRegister, operationCode, operand);

	printf("\n***程序开始执行***\n");

	/*开始执行程序*/
	instructionCounter = 0;
	do
	{
		instructionRegister = memory[instructionCounter];
		operationCode = instructionRegister / 100;
		if (erroperandCode(operationCode) == 0)
		{
			operationCode = 43;
			printf("\n****操作码错误****\n***程序终止执行!\n");
		}
		operand = instructionRegister % 100;
		/*操作选择*/
		switch(operationCode)
		{
			/*读取*/
			case 10:
			{
				printf("?");
				scanf("%d", &memory[operand]);
				printmemory(memory, accumulator, instructionCounter,
					instructionRegister, operationCode, operand);
				++instructionCounter;
				break;
			}

			/*打印*/
			case 11:
			{
				printf("%d \n", memory[operand]);
				printmemory(memory, accumulator, instructionCounter,
					instructionRegister, operationCode, operand);
				++instructionCounter;
				break;
			}

			/*加载*/
			case 20:
			{
				accumulator = memory[operand];
				printmemory(memory, accumulator, instructionCounter,
					instructionRegister, operationCode, operand);
				++instructionCounter;
				break;
			}

			/**/
			case 21:
			{
				memory[operand] = accumulator;
				printmemory(memory, accumulator, instructionCounter,
					instructionRegister, operationCode, operand);
				++instructionCounter;
				break;
			}

			/*加法*/
			case 30:
			{
				accumulator += memory[operand];
				if (errAccumulator(accumulator) == 0)
				{
					operationCode = 43;
					printf("\n***累加器溢出错误***\n***程序将终止执行!\n");
					break;
				}
				else
				{
					printmemory(memory, accumulator, instructionCounter,
						instructionRegister, operationCode, operand);
					++instructionCounter;
					break;
				}
			}

			/*减法*/
			case 31:
			{
				accumulator -= memory[operand];
				if (errAccumulator(accumulator) == 0)
				{
					operationCode = 43;
					printf("\n***累加器溢出错误***\n***程序将终止执行!\n");
					break;
				}
				else
				{
					printmemory(memory, accumulator, instructionCounter,
						instructionRegister, operationCode, operand);
					++instructionCounter;
					break;
				}
			}

			/*除法*/
			case 32:
			{
				accumulator /= memory[operand];
				if (errZero(operand) == 0)
				{
					operationCode = 43;
					printf("\n***累加器溢出错误***\n***程序将终止执行!\n");
					break;
				}
				else
				{
					printmemory(memory, accumulator, instructionCounter,
						instructionRegister, operationCode, operand);
					++instructionCounter;
					break;
				}
			}

			/*乘法*/
			case 33:
			{
				accumulator *= memory[operand];
				if (errAccumulator(accumulator) == 0)
				{
					operationCode = 43;
					printf("\n***乘数为0***\n***程序将终止执行!\n");
					break;
				}
				else
				{
					printmemory(memory, accumulator, instructionCounter,
						instructionRegister, operationCode, operand);
					++instructionCounter;
					break;
				}
			}

			/*jmp*/
			case 40:
			{
				instructionCounter = operand;
				printmemory(memory, accumulator, instructionCounter,
					instructionRegister, operationCode, operand);
				//++instructionCounter;
				break;
				
			}

			/*累加器为负数,跳转*/
			case 41:
			{
				if (accumulator < 0)
				{
					instructionCounter = operand;
					break;
				}
				else
				{
					printmemory(memory, accumulator, instructionCounter,
						instructionRegister, operationCode, operand);
					++instructionCounter;
					break;
				}
			}

			/*acc==zero jmp */
			case 42:
			{
				if (accumulator == 0)
				{
					instructionCounter = operand;
					break;
				}
				else
				{
					printmemory(memory, accumulator, instructionCounter,
						instructionRegister, operationCode, operand);
					++instructionCounter;
					break;
				}
			}

			case 43:
			{
				instructionCounter = operand;
				printf("暂停\n");
				printmemory(memory, accumulator, instructionCounter,
					instructionRegister, operationCode, operand);
				++instructionCounter;
				break;	
			}
			/*默认*/
			default:
				break;
		};
	} while (operationCode != 43);
	return;
}

void printmemory(int m[], int accumulator, int instructionCounter,
	int instructionRegister, int operationCode, int operand)
{
	printf("REGISTERS:\n");
	printf("accumulator          %+05d\n", accumulator);
	printf("instructionCounter      %02d\n", instructionCounter);
	printf("instructionRegister  %+05d\n", instructionRegister);
	printf("operationCode           %02d\n", operationCode);
	printf("operand                 %02d\n\n", operand);
	printf("MEMORY:\n");

	printf("\t0     1     2     3     4     5     6     7     8     9\t");

	for (int i = 0; i < 100; i++)
	{
		if (i % 10 == 0)
		{
			printf("\n");
			printf("%2d  ", i);
		}
		printf("%+05d ", m[i]);
	}
	printf("\n");
}

/*操作码错误*/
int erroperandCode(int operationCode)
{
	if (operationCode == 10 || operationCode == 11 ||
		operationCode == 20 || operationCode == 21 ||
		operationCode == 30 || operationCode == 31 ||
		operationCode == 32 || operationCode == 33 ||
		operationCode == 40 || operationCode == 41 ||
		operationCode == 42 || operationCode == 43)

		return 1;
	else
		return 0;
}


/*除0错误*/
int errZero(int operand)
{
	{
		printf("\n除零错误\n");
	}
	return operand;
}

/*累加器溢出错误*/
int errAccumulator(int accumulator)
{
	if (accumulator > 9999 || accumulator < -9999)
	{
		return 0;
	}

	else
		return -1;
}

第一题的答案SML语言用一个标记控制循环来从键盘上读入10个正数,然后计算并打印它们的和_zhyjhacker的博客-CSDN博客

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值