文档库 最新最全的文档下载
当前位置:文档库 › 计算机导论实验指导

计算机导论实验指导

计算机导论实验指导
计算机导论实验指导

实验0 SimpSim模拟器环境及Visual C++编译调试环境

【实验目的】

1了解自然语言到机器语言的翻译过程

2 熟悉Simple Simulator模拟器环境,掌握使用Simple Simulator模拟程序的执行。

3 掌握SimpSim的单步运行方法,学会单步运行时对存储单元和各寄存器中值的进行

观察。

4 熟悉Visual C++编译调试环境,掌握C语言源程序的建立、编辑、修改、保存。

5 掌握C语言程序的编译和程序调试。

【实验准备】

(1)自然语言到机器语言的翻译过程

任何计算机内部都是用0 和1的序列来表示的,这可以很容易地被计算机理解,但人们却不容易理解,另一方面,无论什么时候,在用像Visual C++ 这样高级语言编写程序的时候,我们使用了能被程序员所理解的一组指令或命令,但计算机却不容易理解。为了在人和机器之间搭建通信的桥梁,制定一个翻译过程是很有必要的。因为每台计算机只能理解它自己的语言(机器语言),所以最终必须将每个程序翻译为用机器语言书写的等价程序,这样计算机就能够理解并执行程序所指定的指令。执行这个翻译过程的计算机程序叫做翻译器,如图1.1 所示。翻译器通常对指定的语言进行工作。也就是说,C 程序的翻译器不能翻译Java语言程序,反之亦然。有两种特定类型的翻译器用来执行高级语言的转换过程:

编译器和解释器。

图1.1 翻译器的基本作用

编译器

翻译过程本身包含一系列对输入语言的转换。图1.2 显示了编译器的通用阶段。虽然对包含在每个阶段的行为的具体讨论超出了本书的范围,但了解翻译过程的一些方面,以及如何与编写的程序进行联系,有利于对计算机程序编译调试过程的理解。

在将程序递交到任何翻译器前,需要使用编辑器或文字处理程序来创建源程序。大部分翻译器需要文件扩展名,将程序保存为特定的类型。例如C 编译器要求包含C程序的文件以“.C ”作为扩展名。如果提交给翻译器的程序没有这个程序没有这个扩展名,编译器就不会对它进行翻译。

一旦创建了程序,它就被递交给预处理程序。正如其名字所指明的一样,该程序在“处理器”或编译器之前进行工作。它可能是一个独立于编译器的程序,也可能是具有不同名称的相同的编译器。预处理程序执行这样的任务,例如将一个或多个文件的内容合并入程序中,并在整个程序中用一个字符串取代另一个字符串。预处理程序扫描整个源代码,寻找“预处

理指令”。这些指令以特定的字符或字符组合开始。例如,C编译器当遇到#include时就将文件并入。同样的编译器在遇到像#define 这样的常量定义时就执行字符串替换操作。

图1.2 编译过程以及连接和装载

当预处理程序完成其任务后,编译器开始执行。编译器的第一个阶段(词法分析阶段) 检查源程序中每个单独的字符并将它们组合成叫着token 或Lexem 的逻辑单元。例如,当C 编译器读取下面的一系列字符时

If (a>b)

a++;

编译器读取到序列“i 后紧跟着f”,在遇到左圆括号后就是一个叫着“if”的逻辑单元,这个“if”和后面的每个字符都被识别并翻译为预定义的数字代码集。这一阶段的逻辑允许编译器识别C 程序中每个可能的有效序列。从程序员的角度来看,这一阶段是很重要的,因为在这里编译器会产生类似“unidentified characters.”(不可识别的字符) 这样的错误。例如,考虑在C 程序中,程序员输入类似,“ń”这样不符合字母表的字符。当编译器“看到”这个字符时,会产生一个错误,通知程序员已经发现了一个不可识别的符号。这种类型的错误属于“fatal errors ”(致命的错误),因为在检测到这样的错误后编译器就停止处理程序并退出。在这一阶段编译器产生的其他错误还有:“program too big”,“unexpected end of file”。后一个错误通常是由于多行注释语句没有结束。

编译器的第二阶段由语法分析器来执行,从程序员的角度来看也是很有意义的,因为在这时编译器要寻找C代码的任何语法错误。可以把这一阶段看作是英文的语法检查功能。例如,假定程序员想要输入赋值语句a=b;但是却输入成了a++b;语法分析的内置逻辑就会把这看作是“无效表达式”并产生错误。在这一阶段遇到的其他错误还有“missing;”( 缺少分号),“Unmatched number of parentless”(圆括号数不匹配),“missing funcution prototype”(没有函数原型等)。

编译器的语义分析阶段,作为一个单独的阶段显示在图1.2中,该阶段有时和语法分析阶段结合在一起。在这一阶段编译器鉴别语句,看是否虽然语法上正确,但却在语言中没有意义。例如,若 a 是一个布尔类型的变量,则赋值语句“a=a+2”,在语法上说是正确的,而在语义上是没有意义的。

代码产生器和代码优化器将最终翻译的程序成为响应的机器语言。根据编译环境中缺省的或已设置的选项,可以在大小方面或速度方面对生成的代码进行优化。大部分编译器喜欢提高速度胜于提高缩短代码。但是,对于编译器来说试图去寻找这两个不兼容选项之间的平衡很寻常。

编译器最后的阶段是目标文件。该文件具有与源文件相同的名字,但扩展名是“.obj”。这个目标文件通常需要涉及驻留在系统中的程序库。就这点而言,程序并没有有做好运行的准备,因为它还有缺少的部分。换句话说,目标文件“知道”仍然需要那些部分但不知道在那里可以找到它们。解决这个问题是另一个系统工具的任务。这个工具叫做连接程序,它找出这些缺少的部分并将其放在合适的地址处。如果连接程序找不到相关的程序,就会产生错误,通知用户并将这一个错误看作是致命的错误,于是中止连接过程。如果连接过程成功了,连接程序输出一个与源文件具有同样名字的文件,但扩展名是“.exe”。这个文件叫做可执行镜象或执行文件。

执行程序时程序及其所需要驻留在内存中,这是一个叫做装载程序的另一个系统工具的任务,它在内存中寻找一个区域并把程序装进来。通常把这个过程称为“装载”可执行镜像到内存中。最后,装载程序给CPU发一个信号,于是程序开始执行。

当程序在运行时,可能会出项“run time” (运行时)错误。这是最难发现的错误,因为一般来说,这是程序逻辑中的错误。这种类型中最通常的错误时访问数组的地址超过了数组的最后一个地址,,或者除数是0,根据编译器所提供的支持不同,这些错误可能很容易发现,也可能很难发现。

在程序编译、连接或运行中出现错误时,程序员应该纠正特定的错误所造成的问题。在计算机术语中,我们把这个过程称为调试。一旦程序员已经找到了错误所在,就需要在编译器中修改源程序,并重新开始编译过程。

解释器

除了编译器,还有叫做解释器的翻译程序。从操作的角度来看,它们之间的主要不同是编译器在程序执行前翻译整个程序。但另一方面,解释器每翻译一条程序语句就执行一条语句。至于考虑这两个翻译器执行的内部处理过程,它们的任务很相似。解释器相对于翻译器的优点是由于编译程序只被翻译一次,所以编译的程序运行速度快。为了描述这两个程序的不同,考虑假想语言编写的循环:

While (a<10000)

c=a*b;

d=a/b;

a=a+1;

End While

该语言的编译器将把每条语句翻译一次,然后执行,10,000次。但同样是对于该语言,解

释器把每条语句翻译10,000,并同时执行10,000次。然而,如果在编写指令时程序员出了错,解释器一旦检测到错误时就会马上产生错误信息。对于编译器来说,直到整个程序编译完成后,程序员才能知道错误。

(2)SimpSim模拟器

SimpSim是《Computer Science: An Overview》中一款配套的模拟器软件,由荷兰Twente 大学的Anne-Gert Bultena编写。

该软件包括如下特点:

?适用于Windows 95/98/NT/XP/Vista,无需安装

?包括run,step和break功能

?内置具有语法高亮提示的汇编语言编辑器及汇编程序

?可读取及保存汇编程序和机器代码

?具有反汇编及跟踪窗口

本书中使用的是SimpSim v2.4,下载地址为:

http://wwwes.cs.utwente.nl/software/simpsim/simpsim.exe。

(3)Visual C++

Visual C++是由微软公司开发的C/C++编译调试工具,Microsoft Visual C++提供了强大和灵活的开发环境,可用于创建基于Microsoft Windows 和基于Microsoft .NET 的应用程序。它既可以用作集成开发系统,也可以用作一组独立的工具。Visual C++ 包含下列组件:Visual C++ 编译器工具。该编译器包含一些新功能,支持面向虚拟计算机平台(如公共语言运行库(CLR))的开发人员。现在已经有面向x64 和Itanium 的编译器。该编译器仍支持直接面向x86 计算机,优化了针对这两种平台的性能。

Visual C++库。其中包括行业标准活动模板库(ATL)、Microsoft 基础类(MFC) 库,以及各种标准库,如标准C++ 库和C 运行时库(CRT)(该库已得到扩展,可以向引起安全问题的已知函数提供安全增强替代项)。新增的库是C++ 支持库,其设计意图在于简化面向CLR 的程序。

Visual C++ 开发环境。虽然可以从命令行使用C++ 编译器工具和库,但开发环境却提供了对项目管理与配置(包括对大型项目的更好支持)、源代码编辑、源代码浏览和调试工具的强大支持。该环境还支持IntelliSense,在编写代码时,该功能可以提供智能化且特定于上下文的建议。

除常规的图形用户界面应用程序外,Visual C++ 还允许开发人员生成Web 应用程序、基于Windows 的智能客户端应用程序以及适用于瘦客户端和智能客户端移动设备的解决方案。C++ 是世界上最流行的系统级语言,而Visual C++ 则为开发人员提供了生成软件的世界级工具。

【实验内容】

1. SimpSim模拟器环境

(1)存储单元A0中值为02、A1中的值为04,将A0、A1中的值相加并把结果存入存储单元A2中。观察最后PC和IR的值。

(2)单步执行以上程序,观察存储单元和各寄存器中值的变化。

2. Visual C++编译调试环境

(1)建立控制台应用程序

(2)编写“Hello World”程序,编译并调试。

【实验步骤】

1. SimpSim 模拟器环境

(1) 双击SimpSim.exe 进入Simple Simulator 模拟器,如图1.1 (2) 将如下机器码填入Main Memory 中的单元格,并给A0、A1赋上初值,如图1.2

图1.1 Simple Simulator 模拟器界面

地址 内容 00 10 01 A0 02 11 03 A1

04 52 05 01 06 32 07 A2 08 C0 09 00

图1.2 输入机器码

(3)单击保存,命名为test.prg

(4)单击Run,程序执行,结果如图1.3,记录PC、IR、R0、R1、R2、A2的值。

图1.3 实验结果

(5)单击Clear,弹出如图1.4的对话框,清空所有数据。

图1.4 清空数据

(6)单击Open,打开刚刚保存的test.prg文件。得到图1.2的界面。

(7)单击Step,程序单步运行,观察每一次PC、IR的变化及R0、R1、R2、A2的值。

2. Visual C++编译调试环境

(1)进入Visual C++环境后,选择File->New菜单弹出New对话框,在Project页面中选择Win32 Console Application项,在Location处选择工程保存路径E:\VCProject,在Project name中填入工程名HelloWorld,Location处的路径会自动添加为E:\VCProject\HelloWorld,如图1.5,单击OK继续。

图1.5 创建新控制台工程

(2)在出现如图1.6所示的Win32 Console Application —Step 1 of 1对话框后,单击Finish按钮出现如图1.7的New Project Information对话框,单击Ok按钮完成工程创建。

图1.6 Win32 Console Application —Step 1 of 1对话框

图1.7 New Project Information对话框

(3)选择File->New菜单,在New对话框的File页选择C++ Source File,在File编辑框中输入文件名hello.c。如图1.8所示。

图1.8 在工程中加入hello.c源程序

(4)单击OK按钮,开始对源文件进行编写,输入如下代码。

(5)选择Build->Build菜单项或按F7键进行编译,系统将会在Output窗口给出所有出错和警告信息。当调试无错误后,选择Build->Execute菜单项,或Ctrl+F5执行程序,得到如图1.9的DOS窗口

图1.9 Hello World实验结果

实验1 数据操作

【实验目的】

?理解指令系统的组成

?掌握机器指令的格式

?理解程序的执行过程

【实验准备】

(1)认真阅读教材3.7.2小节的内容,回答以下问题:

?一条机器指令由几部分组成,分别代表什么含义?

?存储器中的数据是否能直接进行运算,如不能该如何操作?

?CPU中的程序寄存器和指令寄存器在程序的执行过程中分别起什么作用?

?请简述程序的执行过程。

(2)熟悉教材第70页表3.1的内容(机器指令集),对照指令集回答以下问题:?表3.1中的第二条指令和第三条指令都用来“存放”数据,它们之间的区别是什么?

?确定能够读懂此表,试解释23B2、4013、5356所表示的意思。

【实验内容】

(1)验证教材课后习题3.21,要求单步运行,记录每一步寄存器或存储器值的变化(2)设计机器代码,完成以下功能,并在SimpSim上进行验证:

机器代码的首地址从B0开始,单元地址为2F的值为03,寄存器R2的值为05,将2F中的值与R2中的值进行OR运算,结果存入4F中。

【实验步骤】

(1)打开Simpsim.exe,将习题3.21中的机器码及初值输入模拟器中,如图2.1

图2.1 习题6

(2)不断单击Step,观察PC、IR中值的变化

(3)单击Run,观察模拟器的运行。

(4)单击Break终止运行,解释程序不能终止的原因。

(5)单击Clear,清空所有存储单元和寄存器的值

(6)填写如下机器码中【代码1】部分,并输入到SimpSim中

112F

【代码1】

334F

C000

(7)将PC的值设为B0,将2F的值设为03,将R2的值设为05,如图2.2

图2.2

(8)单步运行程序,直到程序结束,记录PC、IR、各寄存器值的变化。

B0: 11,2F load R1,[2F] ;...

B2: 73,12 or R3,R1,R2 ;...

B4: 33,4F store R3,[4F] ;...

B6: C0,00 halt ;...

实验2 结构化程序设计

【实验目的】

?熟悉顺序、选择、循环3种程序结构

?掌握C语言编写选择、循环语句的方法

【实验准备】

(1)认真阅读教材2.4小节、4.2小节的内容,了解算法的有关内容(2)将图3.1所示的流程图片段转换为C语言

图3.1

(3)根据下面的C语言程序,画出其流程图

# include “stdio.h”

main()

{

int sum = 0;

int i = 0;

while(i<10)

{

sum = sum+i;

i++;

}

printf(“sum=%d\n”,sum);

}

【实验内容】

编写程序,求数组a[]={5,34,8,56,6}中最大的数?

【实验步骤】

(1)新建Win32 Console Application工程,工程名为Exp3_1

(2)在Exp3_1工程中,新建exp3_1.c

(3)填写【代码1】【代码2】后,编译、运行并调试源程序

#include "stdio.h"

main()

{

int a[5]={5,34,8,56,6};

int i=0;

int max=0;

while(【代码1】)

{

if(【代码2】)

max = a[i];

i++;

}

printf("数组a[5]中最大的数是%d\n",max); }

实验3 递归与迭代

【实验目的】

?加深理解递归及迭代的概念

?掌握用C语言编写递归及迭代程序的方法

?能够区别递归和迭代之间的差别

【实验准备】

(1)认真阅读教材5.6小节的内容,理解递归和迭代的概念,回答以下问题:?递归和迭代方法,哪一个的时间复杂度高?

?递归和迭代方法是否可以相互转换,转换的意义何在?

(2)斐波那契数列是一个描述了动物繁殖数量、植物花序变化等自然规律的经典数学问题。认真阅读教材4.2.3小节斐波那契问题及5.6小节,思考如何用递归和迭代来

求解斐波那契数列。

【实验内容】

(1)用递归的方法求解斐波那契数列

(2)用迭代的方法求解斐波那契数列

【实验步骤】

(1)新建Win32 Console Application工程,工程名为Exp4_1

(2)在Exp3_1工程中,新建exp4_1.c

(3)填写【代码1】后,编译、运行并调试源程序

#include "stdio.h"

unsigned long F(int n)

{

if(n<=1)

return n;

else

【代码1】;

}

main()

{

int n;

unsigned long sum;

printf(“n=”);

scanf("%d",&n);

sum = F(n);

printf("when n=%d, sum=%d\n",n,sum);

}

(4)新建Win32 Console Application工程,工程名为Exp4_2

(5)在Exp4_2工程中,新建exp4_2.c

(6)填写【代码2】【代码3】【代码4】后,编译、运行并调试源程序

#include "stdio.h"

unsigned long F(int n)

{

int i;

unsigned long a = 0, b = 1, c;

if (n <= 1)

{

【代码2】

}

else

{

for (【代码3】)

{

c = a + b;

a = b;

【代码4】

}

return c;

}

}

main()

{

int n;

unsigned long sum;

printf("n=");

scanf("%d",&n);

sum = F(n);

printf("when n=%d, sum=%d\n",n,sum); }

实验4 数据库设计

【实验目的】

?熟悉ACCESS数据库管理系统的使用;

?熟悉创建数据库、基本表的方法;

?了解主码外码的设定方法及表间的关系;

?掌握查询的创建方法。

【实验准备】

(4)认真阅读教材3.2小节、3.3小节的内容,了解数据库的有关知识。

(5)熟悉ACCESS数据库管理软件的使用。

【实验内容】

掌握数据库管理系统ACCESS软件的使用方法,完成创建数据库、数据表、关系以及查询的对象的创建。

【实验步骤】

(3)打开ACCESS数据库,建立一个学生选课数据库。

(4)创建如下基本表,并为每个表设置主码:

A、学生表结构(图4-1)

B、课程表结构(图4-2)

C、成绩表结构(图4-3)

(5)分别在各表中输入如下数据。

A、学生表数据(图4-4)

B、课程表数据(图4-5)

C、成绩表数据(图4-6)

(6)建立表间多对多的关系,如下图。

表间关系图(图4-7)

(7)建立查询对象,在学生表中查出女生学号、姓名、年龄、性别,并以女学生为查询名保存。

(8)建立查询查出所有不及格的学生的学号、姓名,课程号、课程名、成绩,并以不及格学生为查询名保存。

实验5 算法综合练习

【实验目的】

●熟悉结构化程序设计在算法中的应用

?理解二分查找法的思想

【实验准备】

(1)复习结构化程序设计

(2)复习递归的思想和编写方法

(3)掌握二分查找法

二分查找法又称折半查找法,是一种效率较高的在有序数组中查找特定元素的方法。二分查找法的查找方法是:设有序的为数组a[0…n-1](这里我们假设为递增,递减的情况与此类似),要查询的元素为x,令m = ? (n-1)/2 ?,将x与数组中间的数a[m]进行比较,若x=a[m],则查找成功;若xa[m],则只需在数组的后半段(即区间[m+1,n-1]中)用同样的方法查找x。当相等时,则查找成功;当不相等时,则把下一次查找的区间划分成两半,根据大于和小于的不同情况在不同的区间查找。知道出现区间长度为1的情况时,算法终止。

例1 已知如下11个元素的数组:

a[0…n-1]={4,5,8,10,13,17,20,40,43,48,50},现在要查找元素10和45。

假设指针low和high分别指示待查元素所在范围的下界和上界,指针mid指示区间的中间位置,即mid = ? (low+high)/2 ?。在此例中,low和high的初值分别为1和11。

下面给出x=10的查找过程:

4 5 8 10 13 17 20 40 43 48 50

首先a[mid]与查询值10进行比较,此时a[mid]=17,a[mid]>x,说明待查元素若存在一定在a[mid]的左边,于是缩小范围,将high指到mid-1的位置,重新计算中间位置,此时,a[mid]=8。

4 5 8 10 13 17 20 40 43 48 50

将a[mid]与查询值10进行比较,a[mid]

将a[mid]与查询值10进行比较,结果相等,查找成功。

再看x=45的查找过程:

4 5 8 10 13 17 20 40 43 48 50

首先a[mid]与查询值45进行比较,此时a[mid]=17,a[mid]

4 5 8 10 13 17 20 40 43 48 50

再次将a[mid]与查询值45进行比较,a[mid]

4 5 8 10 13 17 20 40 43 48 50

此时a[mid]>x,说明待查元素若存在一定在a[mid]的左边,于是缩小范围将high指到mid-1的位置,此时因为下界low>上界high,则说明表中没有元素等于45,查找不成功。

4 5 8 10 13 17 20 40 43 48 50

【实验内容】

编写二分查找的C语言程序并进行调试运行

【实验步骤】

相关文档