当前位置:文档之家› OpenMP程序的编译和运行

OpenMP程序的编译和运行

OpenMP程序的编译和运行
OpenMP程序的编译和运行

SHANGHAI UNIVERSITY

学院计算机工程与科学学院实验OpenMP程序的编译和运行姓名陈帅

学号12122208

教师刘芳芳

时间2015.05.06

报告成绩

实验2-1. OpenMP程序的编译和运行

1.实验目的

1) 在Linux平台上编译和运行OpenMP程序;

2) 在Windows平台上编译和运行OpenMP程序。

3) 掌握OpenMP并行编程基础。

2.实验环境

1) 硬件环境:计算机一台;

2) 软件环境:Linux、Win2003、GCC、MPICH、VS2008或其他版本Visual Studio;

3.实验内容

1. Linux下OpenMP程序的编译和运行。OpenMP是一个共享存储并行系统上的应用编程接口,支持C/C++和FORTRAN等语言,编译和运行简单的"Hello World"程序。在Linux下编辑hellomp.c源程序,或在Windows下编辑并通过附件中的FTP工具(端口号:1021)上传,用"gcc -fopenmp -O2 -o hellomp.out hellomp.c"命令编译,用"./hellomp.out"命令运行程序。注:在虚拟机中当使用vi编辑文件时,不是以ESC键退出插入模式,可以使用“Ctrl+c”进入命令模式,然后输入wq进行存盘退出。

代码如下:

#include

#include

int main()

{

int nthreads,tid;

omp_set_num_threads(8);

#pragma omp parallel private(nthreads,tid)

{

tid=omp_get_thread_num();

printf("Hello World from OMP thread %d\n",tid);

if(tid==0)

{

nthreads=omp_get_num_threads();

printf("Number of threads is %d\n",nthreads);

}

}

}

安装gcc

检查GCC是否安装完成

编写hellomp.c

编译运行

2.控制并行执行的线程数。

根据算法的要求和硬件情况,例如CPU数量或者核数,选择适合的线程数可以加速程序的运行。请按照下列的方法进行线程数量的设置。

//设置线程数为10

[xuyc@sv168 openmp]$ OMP_NUM_THREADS=10

//将线程数添加为环境变量

[xuyc@sv168 openmp]$ export OMP_NUM_THREADS

//运行

修改hellomp.c程序,删除omp_set_num_threads(8);语句

如果不定义OMP_NUM_THREADS,默认会等于CPU数量,在8核心的机器上,会打印出8行"Hello World".

omp_set_num_threads(8);设置了子线程数为8,即是可以有8个子线程并行运行。

#pragma omp parallel private(nthreads,tid)为编译制导语句,每个线程都自己的nthreads 和tid两个私有变量,线程对私有变量的修改不影响其它线程中的该变量。

程序的功能是对于每个线程都打印出它的id号,对于id号为0的线程打印出线程数目。

2. Windows下OpenMP程序的编译和运行。用VS2013编辑上述的hellomp.c源程序,注意在菜单“项目->属性->C/C++->语言”选中“OpenMP支持”,编译并运行程序。

打开或者新建一个c++项目,依次选择Project -> 属性 -> 配置属性(configuration property) -> c/c++ -> 语言(Language),打开OpenMP支持;

设置环境变量OMP_NUM_THREADS。

设置环境变量:我的电脑 -> 属性 -> 高级 -> 环境变量,新建一个

OMP_NUM_THREADS变量,值设为2,即为程序执行的线程

数。

图3 VS2013使用界面

使用VS2013进行并行程序设计,图3为VS2013使用界面,图4为运行结果截图。

图4 程序运行结果截图

虽然线程都是一起开始运行,但实验中每次运行的结果都不一样,这个是因为每次每个线程结束的先后可能不一样的。所以每次运行的结果都是随机的。这是串行程序和并行程序不同的地方:串行程序可以重新运行,结果和之前一样;并行程序却因为执行次序无法控制可能导致每次的结果都不一样。

实验2-2 矩阵乘法的OpenMP实现及性能分析

1.实验目的

1) 用OpenMP实现最基本的数值算法“矩阵乘法”

2) 掌握for编译制导语句

3) 对并行程序进行简单的性能调优

2.实验内容

1)运行并测试OpenMP编写两个n阶的方阵a和b的相乘程序,结果存放在方阵c中,其中乘法用for编译制导语句实现并行化操作,并调节for编译制导中schedule的参数,使得执行时间最短。要求在window环境(不用虚拟机),在linux环境(用和不用虚拟机情况下)测试程序的性能,并写出详细的分析报告。

源代码如下:

#include

#include

#include

void comput(float* A,float* B,float* C)//两个矩阵相乘传统方法

{

int x,y;

for(y=0;y<4;y++)

{

for(x=0;x<4;x++)

{

C[4*y+x]= A[4*y+0]*B[4*0+x]+ A[4*y+1]*B[4*1+x]+

A[4*y+2]*B[4*2+x]+ A[4*y+3]*B[4*3+x];

}

}

}

int main()

{

double duration;

clock_t s,f;

int x=0;

int y=0;

int n=0;

int k=0;

float A[]={1,2,3,4,

5,6,7,8,

9,10,11,12,

13,14,15,16};

float B[]={0.1f,0.2f,0.3f,0.4f,

0.5f,0.6f,0.7f,0.8f,

0.9f,0.10f,0.11f,0.12f,

0.13f,0.14f,0.15f,0.16f};

float C[16];

s= clock();

//#pragma omp parallel if(false)

for(n=0;n<1000000;n++)

{

comput(A,B,C);

}

f=clock();

duration =(double)(f - s)/CLOCKS_PER_SEC; printf("s---1,000,000 :%f\n",duration);

for(y=0;y<4;y++)

{

for(x=0;x<4;x++)

{

printf("%f,",C[y*4+x]);

}

printf("\n");

}

printf("\n======================\n");

s = clock();

//parallel 2

#pragma omp parallel for

for(n=0;n<2;n++)////CPU是核线程的

{

for(k=0;k<1000000;k++)//每个线程管个循环

{

comput(A,B,C);

}

}

f = clock();

duration =(double)(f - s)/CLOCKS_PER_SEC;

printf("p2- 1,000,000:%f\n",duration);

//parallel 3

s = clock();

#pragma omp parallel for

for(n=0;n<4;n++)//CPU是核线程的

{

for(k=0;k<1000000;k++)//每个线程管个循环

{

comput(A,B,C);

}

}

f = clock();

duration =(double)(f - s)/CLOCKS_PER_SEC; printf("p3- 1,000,000:%f\n",duration);

//parallel 1

s = clock();

#pragma omp parallel for

for(n=0;n<1000000;n++)

{

comput(A,B,C);

}

f = clock();

duration =(double)(f - s)/CLOCKS_PER_SEC; printf("p1- 1,000,000 :%f\n",duration);

for(y=0;y<4;y++)

{

for(x=0;x<4;x++)

{

printf("%f,",C[y*4+x]);

}

printf("\n");

}

return0;

}

程序运行结果:

分析报告:

由运行结果可以看出串行运算1000000次s-1的时间是0.030000,

并行运算1000000次p-1的时间是0.040000,并行的时间比串行还要久一点,原因在于对计算机来说计算1000000万次的此矩阵计算是非常easy的事情,计算量很小,在这种情况下OMP多线程计算时,线程的创建和销毁的开销会变成主要的消耗时间。

p-2是2线程运算,p-3是4线程运算,所以在同样运算1000000次的情况下,p-2的时间要比p-3的时间多出来0.010000秒。

2)请自己找一个需要大量计算但是程序不是很长的程序,实现OMP的多线程并行计算,要求写出并行算法,并分析并行的效果(注:必须核对串行和并行的计算结果,保证正确性)#include

#include

#include

using namespace std;

void qh (int i)

{

float sum =0;

int j;

for(int j =1; j <= i; j++)

sum += sqrt(j);

}

void qh1(int i)//计算1到i平方根的和

{

float sum =0;

int j;

for(int j =1; j <= i; j++)

sum += sqrt(j);

cout<<"sum="<< sum<

}

int main()

{

int i =10;

clock_t s, f;

s = clock();

double duration;

int x =0;

int y =0;

int n =0;

int k =0;

//#pragma omp parallel if(false)

for(n =0; n<1000000; n++)

{

qh(i);

}

qh1(i);

f = clock();

duration =(double)(f - s)/ CLOCKS_PER_SEC; printf("s---1,000,000 :%f\n", duration);

printf("\n======================\n");

s = clock();

//parallel 2

#pragma omp parallel for

for(n =0; n<2; n++)////CPU是核线程的

{

for(k =0; k<500000; k++)//每个线程管个循环

{

qh(i);

}

}

qh1(i);

f = clock();

duration =(double)(f - s)/ CLOCKS_PER_SEC; printf("p2-500,000:%f\n", duration);

//parallel 3

s = clock();

#pragma omp parallel for

for(n =0; n<4; n++)//CPU是核线程的

{

for(k =0; k<250000; k++)//每个线程管个循环

{

qh(i);

}

}

qh1(i);

f = clock();

duration =(double)(f - s)/ CLOCKS_PER_SEC;

printf("p3- 250,000:%f\n", duration);

//parallel 4

s = clock();

#pragma omp parallel for

for(n =0; n<4; n++)//CPU是核线程的

{

for(k =0; k<500000; k++)//每个线程管个循环

{

qh(i);

}

}

qh1(i);

f = clock();

duration =(double)(f - s)/ CLOCKS_PER_SEC;

printf("p4- 500,000:%f\n", duration);

//parallel 1

s = clock();

#pragma omp parallel for

for(n =0; n<1000000; n++)

{

qh(i);

}

qh1(i);

f = clock();

duration =(double)(f - s)/ CLOCKS_PER_SEC;

printf("p1- 1,000,000 :%f\n", duration);

system("pause");

return0;

}

运行结果:

结果分析:

程序计算的是1到10 的平方根的和,由运行结果可以看出,串行运算s-1的时间比并行运算p-1的时间要稍短一些,这是因为并行运算有创建和销毁线程的时间,当计算量比较少时,这部分的时间就变为主要的消耗时间。

p-2是以2线程运算500000次,p-4是以4线程运算500000次,由p-4比p-2多出的0.438000时间可以看出多创建2个线程是非常消耗时间的(运算量较少时)。P-3是以4线程运算250000次,耗时同p-2相同,说明在计算量小的情况下使用OMP多核线程是非常划不来的。

总之,OMP并行多核线程技术适用于计算量很大时使用,这是线程创建和销毁的时间就可以忽略不计,对于计算量小的运算,还是串行运算靠谱。

编译实验报告+源代码

课程设计报告 ( 2013-- 2014年度第1学期) 名称:编译技术课程设计B 题目:简单编译程序的设计与实现院系:计算机系 班级:XXX 学号:XXX 学生姓名:XXX 指导教师:XXX 设计周数:XXX 成绩: 日期:XX 年XX 月

实验一.词法分析器的设计与实现 一、课程设计(综合实验)的目的与要求 1.1 词法分析器设计的实验目的 本实验是为计算机科学与技术专业的学生在学习《编译技术》课程后,为加深对课堂教学内容的理解,培养解决实际问题能力而设置的实践环节。通过这个实验,使学生应用编译程序设计的原理和技术设计出词法分析器,了解扫描器的组成结构,不同种类单词的识别方法。能使得学生在设计和调试编译程序的能力方面有所提高。为将来设计、分析编译程序打下良好的基础。 1.2 词法分析器设计的实验要求 设计一个扫描器,该扫描器是一个子程序,其输入是源程序字符串,每调用一次识别并输出一个单词符号。为了避免超前搜索,提高运行效率,简化扫描器的设计,假设该程序设计语言中,基本字(也称关键词)不能做一般标识符用,如果基本字、标识符和常数之间没有确定的运算符或界符作间隔,则用空白作间隔。 单词符号及其内部表示如表1-1所示,单词符号中标识符由一个字母后跟多个字母、数字组成,常数由多个十进制数字组成。单词符号的内部表示,即单词的输出形式为二元式:(种别编码,单词的属性值)。 表1-1 单词符号及其内部表示

二、设计(实验)正文 1.词法分析器流程图 2.词法分析器设计程序代码 // first.cpp : 定义控制台应用程序的入口点。// #include"stdafx.h" #include #include using namespace std; int what(char a) { if((int(a)>=48)&&(int(a)<=57)) {

清华大学版编译原理答案

《编译原理》课后习题 第1 章引论 第1 题解释下列术语: (1)编译程序:如果源语言为高级语言,目标语言为某台计算机上的汇编语言或机器语言,则此翻译程序称为编译程序。 (2)源程序:源语言编写的程序称为源程序。 (3)目标程序:目标语言书写的程序称为目标程序。 (4)编译程序的前端:它由这样一些阶段组成:这些阶段的工作主要依赖于源语言而与目标机无关。通常前端包括词法分析、语法分析、语义分析和中间代码生成这些阶 段,某些优化工作也可在前端做,也包括与前端每个阶段相关的出错处理工作和符 号表管理等工作。 (5)后端:指那些依赖于目标机而一般不依赖源语言,只与中间代码有关的那些阶段,即目标代码生成,以及相关出错处理和符号表操作。 (6)遍:是对源程序或其等价的中间语言程序从头到尾扫视并完成规定任务的过程。 第2 题 一个典型的编译程序通常由哪些部分组成?各部分的主要功能是什么?并画出编译程 序的总体结构图。 答案:一个典型的编译程序通常包含8 个组成部分,它们是词法分析程序、语法分析程序、语义分析程序、中间代码生成程序、中间代码优化程序、目标代码生成程序、表格管理程序和错误处理程序。其各部分的主要功能简述如下。 词法分析程序:输人源程序,拼单词、检查单词和分析单词,输出单词的机内表达形式。语法分析程序:检查源程序中存在的形式语法错误,输出错误处理信息。 语义分析程序:进行语义检查和分析语义信息,并把分析的结果保存到各类语义信息表中。 中间代码生成程序:按照语义规则,将语法分析程序分析出的语法单位转换成一定形式 的中间语言代码,如三元式或四元式。 中间代码优化程序:为了产生高质量的目标代码,对中间代码进行等价变换处理。 目标代码生成程序:将优化后的中间代码程序转换成目标代码程序。 表格管理程序:负责建立、填写和查找等一系列表格工作。表格的作用是记录源程序的 各类信息和编译各阶段的进展情况,编译的每个阶段所需信息多数都从表格中读取,产生的中间结果都记录在相应的表格中。可以说整个编译过程就是造表、查表的工作过程。需要指出的是,这里的“表格管理程序”并不意味着它就是一个独立的表格管理模块,而是指编译程序具有的表格管理功能。 错误处理程序:处理和校正源程序中存在的词法、语法和语义错误。当编译程序发现源 程序中的错误时,错误处理程序负责报告出错的位置和错误性质等信息,同时对发现的错误进行适当的校正(修复),目的是使编译程序能够继续向下进行分析和处理。 第3 题何谓翻译程序、编译程序和解释程序?它们三者之间有何种关系? 答案:翻译程序是指将用某种语言编写的程序转换成另一种语言形式的程序的程序,如编译程序和汇编程序等。 编译程序是把用高级语言编写的源程序转换(加工)成与之等价的另一种用低级语言编 写的目标程序的翻译程序。 解释程序是解释、执行高级语言源程序的程序。解释方式一般分为两种:一种方式是, 源程序功能的实现完全由解释程序承担和完成,即每读出源程序的一条语句的第一个单词,则依据这个单词把控制转移到实现这条语句功能的程序部分,该部分负责完成这条语句的功

编译原理考试试卷

一、填空题(每空2分,共30分) 1、编译程序的整个过程可以从逻辑上划分为词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等几个阶段,另外还有两个重要的工作是表格管理和出错处理 2、规范规约中的可归约串是句柄,算符优先分析中的可归约串是最左素短语。 3、语法分析方法主要可分为自顶向下和自底向上两大类。 4、LR(0)文法的项目集中不会出现移进-归约冲突和归约-归约冲突。 5、数据空间的动存态储分配方式可分为栈式和堆式两种。 6、编译程序是指能将源语言程序翻译成目标语言程序的程序。 7、确定有穷自动机DFA是NFA 的一个特例。 8、表达式(a+b)*c 的逆波兰表示为ab+c* 。 二、选择题(每题2分,共20分) 1、L R语法分析栈中存放的状态是识别 B 的DFA状态。 A、前缀 B、可归前缀 C、项目 D、句柄 2、 D 不可能是目标代码。 A、汇编指令代码 B、可重定位指令代码 C、绝对机器指令代码 D、中间代码 3、一个控制流程图就是具有 C 的有向图 A、唯一入口结点 B、唯一出口结点 C、唯一首结点 D、唯一尾结点 4、设有文法G[S]:S→b|bB B→bS ,则该文法所描述的语言是 C 。 A、L(G)={b i|i≥0} B、L(G)={b2i|i≥0} C、L(G)={b2i+1|i≥0} D、L(G)={b2i+1|i≥1} 5、把汇编语言程序翻译成机器可执行的目标程序的工作是由 B 完成的。 A、编译器 B、汇编器 C、解释器 D、预处理器 6、在目标代码生成阶段,符号表用于 D 。 A、目标代码生成 B、语义检查 C、语法检查 D、预处理器地址分配0 7、规范归约是指 B 。 A、最左推导的逆过程 B、最右推导的逆过程 C、规范推导 D、最左归约逆过程

编译原理(PL0编译程序源代码)

/*PL/0编译程序(C语言版) *编译和运行环境: *Visual C++6.0 *WinXP/7 *使用方法: *运行后输入PL/0源程序文件名 *回答是否将虚拟机代码写入文件 *回答是否将符号表写入文件 *执行成功会产生四个文件(词法分析结果.txt符号表.txt虚拟代码.txt源程序和地址.txt) */ #include #include"pl0.h" #include"string" #define stacksize 500//解释执行时使用的栈 int main(){ bool nxtlev[symnum]; printf("请输入源程序文件名:"); scanf("%s",fname); fin=fopen(fname,"r");//以只读方式打开pl0源程序文件 cifa=fopen("词法分析结果.txt","w"); fa1=fopen("源程序和地址.txt","w");//输出源文件及各行对应的首地址 fprintf(fa1,"输入pl0源程序文件名:"); fprintf(fa1,"%s\n",fname); if(fin){ printf("是否将虚拟机代码写入文件?(Y/N)");//是否输出虚拟机代码 scanf("%s",fname); listswitch=(fname[0]=='y'||fname[0]=='Y'); printf("是否将符号表写入文件?(Y/N)");//是否输出符号表scanf("%s",fname); tableswitch=(fname[0]=='y'||fname[0]=='Y'); init();//初始化 err=0; cc=cx=ll=0; ch=' '; if(-1!=getsym()){ fa=fopen("虚拟代码.txt","w"); fas=fopen("符号表.txt","w"); addset(nxtlev,declbegsys,statbegsys,symnum); nxtlev[period]=true; if(-1==block(0,0,nxtlev)){//调用编译程序 fclose(fa); fclose(fa1); fclose(fas); fclose(fin); return 0; } if(sym!=period){ error(9);//结尾丢失了句号 }

linux实验报告3 Linux上C程序编译,调试和工程文件管理

深圳大学实验报告 课程名称:Linux操作系统 实验项目名称:Linux上C程序编译,调试和工程文件管理学院:计算机与软件学院 专业:软件工程 指导教师:冯禹洪 报告人:文成学号:2011150259 班级:02 实验时间:2013/12/31 实验报告提交时间:2013/12/31 教务处制

一、实验目标: 熟悉Linux上C程序设计环境,包括以下内容: 1. 联机帮助man命令 2. 编译工具gcc的使用 3. 熟悉使用gdb来调试程序 4. 熟悉C工程文件的管理工具makefile 二、实验环境与工件 湖边Linux实验室 Fedora 13 三、实验内容与步骤 1.动态库函数可以在多个应用程序之间共享,可以减少应用程序文件的容量和 应用程序的装载时间。因此,熟悉构建动态库可以提高软件的编写质量。请跟随以下步骤构建动态库message,并用其编写程序、编译和运行。(40分) 1.1编写源程序message.c(见图1)和main.c(见图2) 图1. message.c源程序 图2.main.c源程序 1.2用以下命令对message.c进行编译,其中,“-fPIC”选项是告诉gcc产生的 代码不要包含对函数和变量具体内存位置的引用。

1.3以上命令将获得目标文件message.o,使用以下命令建立共享函数库 message: 1.4使用1.3获得的共享函数库来编译main.c文件 1.5设置共享函数库搜索路径 1.6运行程序并附上结果 1.7构建静态可执行程序 1.7.1$gcc –c message.c 1.7.2$ar –crv libmsg.a message.o 1.7.3$gcc –o main main.c –L./ -lmsg 1.7.4$./main 1.8运行以下两个命令并截图说明结果: $ldd goodbye $ldd main $ls –l goodbye main /*附加题:经观察,如果用ubuntu, main 和googbye的大小在一些发行版本下没有区别,如果实验如此,请尝试解释这一现象。附加题目,平时成绩+5分,超过40分不算。*/ 2.图3-4中的reverse程序是有bug的,请使用gdb去观察程序的行为,对关键 行为截图说明,定位错误(截图说明)并修正程序bug。附上修正的程序及其运行结果。(40分) 图3. reverse.h头文件

编译原理作业参考答案

第1章引言 1、解释下列各词 源语言:编写源程序的语言(基本符号,关键字),各种程序设计语言都可以作为源语言。 源程序: 用接近自然语言(数学语言)的源语言(基本符号,关键字)编写的程序,它是翻译程序处理的对象。 目标程序: 目标程序是源程序经过翻译程序加工最后得到的程序。目标程序 (结果程序)一般可由计算机直接执行。 低级语言:机器语言和汇编语言。 高级语言:是人们根据描述实际问题的需要而设计的一个记号系统。如同自然语言(接近数学语言和工程语言)一样,语言的基本单位是语句,由符号组和一组用来组织它们成为有确定意义的组合规则。 翻译程序: 能够把某一种语言程序(源语言程序)改变成另一种语言程序(目标语言程序),后者与前者在逻辑上是等价的。其中包括:编译程序,解释程序,汇编程序。 编译程序: 把输入的源程序翻译成等价的目标程序(汇编语言或机器语言), 然后再执行目标程序(先编译后执行),执行翻译工作的程序称为编译程序。 解释程序: 以该语言写的源程序作为输入,但不产生目标程序。按源程序中语句动态顺序逐句的边解释边执行的过程,完成翻译工作的程序称为解释程序。 2、什么叫“遍”? 指对源程序或源程序的中间形式(如单词,中间代码)从头到尾扫描一次,并作相应的加工处理,称为一遍。 3、简述编译程序的基本过程的任务。 编译程序的工作是指从输入源程序开始到输出目标程序为止的整个过程,整个过程可以划分5个阶段。 词法分析:输入源程序,进行词法分析,输出单词符号。 语法分析:在词法分析的基础上,根据语言的语法规则把单词符号串分解成各类语法单位,并判断输入串是否构成语法正确的“程序”。 中间代码生成:按照语义规则把语法分析器归约(或推导)出的语法单位翻译成一定形式的中间代码。 优化:对中间代码进行优化处理。 目标代码生成:把中间代码翻译成目标语言程序。 4、编译程序与解释程序的区别? 编译程序生成目标程序后,再执行目标程序;然而解释程序不生成目标程序,边解释边执行。 5、有人认为编译程序的五个组成部分缺一不可,这种看法正确吗? 编译程序的5个阶段中,词法分析,语法分析,语义分析和代码生成生成是必须完成的。而中间代码生成和代码优化并不是必不可少的。优化的目的是为了提高目标程序的质量,没有这一部分工作,仍然能够得到目标代码。 6、编译程序的分类 目前基本分为:诊断编译程序,优化编译程序,交叉编译程序,可变目标编译程序。

VC++6.0中如何编译运行及调试C语言程序

VC++6.0中如何编译运行调试C语言程序1.启动VC++6.0 (如下图) 2.单个源文件的编译运行 例如下面的源代码 #include void main() { int i,sum=0; for(i=1;i<=10;i++) { sum=sum+i; } printf("sum=%d\n",sum); }

打开VC++6.0,如图1所示 (图1)选择“文件”→“新建”,打开如图2所示 (图2)

选择“文件”项,如图3所示 (图3) 选择“C++ Source File”项,并在“文件名”项目下输入“sum.c”如图4所示 (图4)

单击“确定”,打开如图5所示 (图5) 输入如上源代码,如图6所示 (图6) 选择按编译按钮调试程序,看看有没有错误,有的话改正,没有的话就可以再按连接按钮检查连接(多文件工程时常用,检查文件间是否正常连接)。

(图7) 在下端的输出窗口会有错误和警告的提示,如果没有错误选择“执行”(或按Ctrl+F5组合键)即可出现运行结果,如图8所示 (图8)

3.多个源文件的编译运行 以上是运行单个源文件的情况,但是在程序设计时,往往是由几个人各自独立编写不同的程序,显然这些程序是不能写在一起进行编译的,这时就需要建立项目工作区来完成几个独立程序的编译,具体方法如下。 首先建立两个文本文件,分别命名为“file1.c”和“file.c”,分别在两个文件中输入如下两个源代码,然后保存。 源代码1: #include void main() { void sum(); sum(); } 源代码2: #include void sum() { int i,sum=0; for(i=1;i<=10;i++) { sum=sum+i; } printf("sum=%d\n",sum); } 打开VC++6.0,选择“文件”→“新建”打开如图9所示

编译原理实验:目标代码的生成

5. 目标代码生成 本章实验为实验四,是最后一次实验,其任务是在词法分析、语法分析、语义分析和中间代码生成程序的基础上,将C 源代码翻译为MIPS32指令序列(可以包含伪指令),并在SPIM Simulator上运行。当你完成实验四之后,你就拥有了一个自己独立编写、可以实际运行的编译器。 选择MIPS作为目标体系结构是因为它属于RISC范畴,与x86等体系结构相比形式简单便于我们处理。如果你对于MIPS体系结构或汇编语言不熟悉并不要紧,我们会提供详细的参考资料。 需要注意的是,由于本次实验的代码会与之前实验中你已经写好的代码进行对接,因此保持一个良好的代码风格、系统地设计代码结构和各模块之间的接口对于整个实验来讲相当重要。 5.1 实验内容 5.1.1 实验要求 为了完成实验四,我们建议你首先下载并安装SPIM Simulator用于对生成的目标代码进行检查和调试,SPIM Simulator的官方下载地址为:https://www.doczj.com/doc/7e14497304.html,/~larus/spim.html。这是由原Wisconsin-Madison的Jame Larus教授(现在在微软)领导编写的一个功能强大的MIPS32汇编语言的汇编器和模拟器,其最新的图形界面版本QtSPIM由于使用了Qt组件因而可以在各大操作系统平台如Windows、Linux、Mac等上运行,推荐安装。我们会在后面介绍有关SPIM Simulator的使用方法。 你需要做的就是将实验三中得到的中间代码经过与具体体系结构相关的指令选择、寄存器选择以及栈管理之后,转换为MIPS32汇编代码。我们要求你的程序能输出正确的汇编代码。“正确”是指该汇编代码在SPIM Simulator(命令行或Qt版本均可)上运行结果正确。因此,以下几个方面不属于检查范围: 1)寄存器的使用与指派可以不必遵循MIPS32的约定。只要不影响在SPIM Simulator中的 正常运行,你可以随意分配MIPS体系结构中的32个通用寄存器,而不必在意哪些寄存器应该存放参数、哪些存放返回值、哪些由调用者负责保存、哪些由被调用者负责保存,等等。 2)栈的管理(包括栈帧中的内容及存放顺序)也不必遵循MIPS32的约定。你甚至可以使 用栈以外的方式对过程调用间各种数据的传递进行管理,前提是你输出的目标代码(即MIPS32汇编代码)能运行正确。

编译原理

一、选择 1.将编译程序分成若干个“遍”是为了_使程序的结构更加清晰__。 2.正规式 MI 和 M2 等价是指__.M1 和 M2 所识别的语言集相等_。 3.中间代码生成时所依据的是 _语义规则_。 4.后缀式 ab+cd+/可用表达式__(a+b)/(c+d)_来表示。 6.一个编译程序中,不仅包含词法分析,_语法分析 ____,中间代码生成,代码优化,目标代码生成等五个部分。 7.词法分析器用于识别__单词___。 8.语法分析器则可以发现源程序中的___语法错误__。 9.下面关于解释程序的描述正确的是__解释程序的特点是处理程序时不产生目标代码 ___。 10.解释程序处理语言时 , 大多数采用的是__先将源程序转化为中间代码 , 再解释执行___方法。 11.编译过程中 , 语法分析器的任务就是__(2)(3)(4)___。 (1) 分析单词是怎样构成的 (2) 分析单词串是如何构成语句和说明的 (3) 分析语句和说明是如何构成程序的 (4) 分析程序的结构 12.编译程序是一种__解释程序__。 13.文法 G 所描述的语言是_由文法的开始符号推出的所有终极符串___的集合。 14.文法分为四种类型,即 0 型、1 型、2 型、3 型。其中 3 型文法是___正则文法__。 15.一个上下文无关文法 G 包括四个组成部分,它们是:一组非终结符号,一组终结符号,一个开始符号,以及一组 _产生式__。 16.通常一个编译程序中,不仅包含词法分析,语法分析,中间代码生成,代码优化,目标代码生成等五个部分,还应包括_表格处理和出错处理__。 17.文法 G[N]= ( {b} , {N , B} , N , {N→b│ bB , B→bN} ),该文法所描述的语言是L(G[N])={b2i+1│ i ≥0} 18.一个句型中的最左_简单短语___称为该句型的句柄。 19.设 G 是一个给定的文法,S 是文法的开始符号,如果 S->x( 其中 x∈V*), 则称 x 是 文法 G 的一个__句型__。 21.若一个文法是递归的,则它所产生的语言的句子_是无穷多个___。 22.词法分析器用于识别_单词_。 23.在语法分析处理中, FIRST 集合、 FOLLOW 集合、 SELECT 集合均是_终极符集 ___。 24.在自底向上的语法分析方法中,分析的关键是_寻找句柄 ___。 25.在 LR 分析法中,分析栈中存放的状态是识别规范句型__活前缀__的 DFA 状态。 26.文法 G 产生的__句子___的全体是该文法描述的语言。 27.若文法 G 定义的语言是无限集,则文法必然是 __递归的_ 28.四种形式语言文法中,1 型文法又称为 _短语结构文法__文法。 29.一个文法所描述的语言是_唯一的__。 30. _中间代码生成___和代码优化部分不是每个编译程序都必需的。 31._解释程序和编译程序___是两类程序语言处理程序。 32.数组的内情向量中肯定不含有数组的_维数___的信息。 33. 一个上下文无关文法 G 包括四个组成部分,它们是:一组非终结符号,一组终结符号,一个开始符号,以及一组__D___。 34.文法分为四种类型,即 0 型、1 型、2 型、3 型。其中 2 型文法是__上下文无关文法__。 35.一个上下文无关文法 G 包括四个组成部分,它们是:一组非终结符号,一组终结符号,一个开始符号,以及一组 __产生式___。 36.__ BASIC ___是一种典型的解释型语言。 37.与编译系统相比,解释系统___比较简单 , 可移植性好 , 执行速度慢__。 38.用高级语言编写的程序经编译后产生的程序叫__目标程序___。 39.编写一个计算机高级语言的源程序后 , 到正式上机运行之前,一般要经过__(1)(2)(3)__这几步: (1) 编辑 (2) 编译 (3) 连接 (4) 运行 40.把汇编语言程序翻译成机器可执行的目标程序的工作是由__编译器__完成的。 41.词法分析器的输出结果是__单词的种别编码和自身值__。 42.文法 G :S→xSx|y 所识别的语言是_ xnyxn(n≥0)___。 43.如果文法 G 是无二义的,则它的任何句子α__最左推导和最右推导对应的语法树必定相同_。 44.构造编译程序应掌握___源程序目标语言编译方法___。 45.四元式之间的联系是通过__临时变量___实现的。 46.表达式( ┐ A ∨B)∧(C∨D)的逆波兰表示为___ A ┐ B∨CD∨∧__。 47. 优化可生成__运行时间短且占用存储空间小___的目标代码。 48.下列__删除多余运算 ____优化方法不是针对循环优化进行的。 49.编译程序使用__说明标识符的过程或函数的静态层次___区别标识符的作用域。 50.编译程序绝大多数时间花在___表格管理__ 上。 51.编译程序是对__高级语言的翻译___。

TurboC程序设计的基本步骤及如何编译、调试和运行源程序

Turbo C程序设计的基本步骤及如何编译、调试和运行源程序 本节主要介绍Turbo C程序设计的基本步骤及如何编译、调试和运行源程序。并给出Turbo C的常用编辑命令。最后介绍Turbo C编译、连接和运行时的常见错误。 一、Turbo C程序设计基本步骤 程序设计方法包括三个基本步骤: 第一步:分析问题。 第二步:画出程序的基本轮廓。 第三步:实现该程序。 3a.编写程序 3b.测试和调试程序 3c.提供数据打印结果 下面,我们来说明每一步的具体细节。 第一步:分析问题 在这一步,你必须: a. 作为解决问题的一种方法,确定要产生的数据(输出)。作为这一子步的一部分你应定义表示输出的变量。 b. 确定需产生输出的数据(称为输入),作为这一子步的一部分,你应定义表示输入的变量。 c. 研制一种算法,从有限步的输入中获取输出。这种算法定义为结构化的顺序操作,以便在有限步解决问题。就数字问题而言,这种算法包括获取输出的计 Word文档资料

算,但对非数字问题来说,这种算法包括许多文本和图象处理操作。 第二步:画出程序的基本轮廓 在这一步,你要用一些句子(伪代码)来画出程序的基本轮廓。每个句子对应一个简单的程序操作。对一个简单的程序来说,通过列出程序顺序执行的动作,便可直接产生伪代码。然而,对复杂一些的程序来说,则需要将大致过程有条理地进行组织。对此,应使用自上而下的设计方法。 当使用自上而下的设计方法时,你要把程序分割成几段来完成。列出每段要实现的任务,程序的轮廓也就有了,这称之为主模块。当一项任务列在主模块时,仅用其名加以标识,并未指出该任务将如何完成。这方面的容留给程序设计的下一阶段来讨论。将程序分为几项任务只是对程序的初步设计。整个程序设计归结为下图所示的流程图1. 0 1 1主模块 1 I 1 1 I 输入数据I 1主模块I I计算购房所需的金额I 1 I I计算装修所需的金额I 1任务1I I计算总金额I 1任务2I I输出计算结果I 1任务3I I I 1任务4I 1 ---------------- 1 -------------------- 1 I I I——1II——1II——1II1II——1I 1 ---------------------- 1 I输入数据II购房额?? II装修额..I I总额..I I输出 Word文档资料

(完整word版)PL0源代码(C语言版)

/*PL/0 编译系统C版本头文件pl0.h*/ # define norw 13 //a number of reserved word /*关键字个数*/ # define txmax 100 //length of identifier table /*名字表容量*/ # define nmax 14 //max number of digits in numbers /*number的最大位数*/ # define al 10 //length of identifier /*符号的最大长度*/ # define amax 2047 //maximum address /*地址上界*/ # define levmax 3 //max depth of block nesting /*最大允许过程嵌套声明层数[0,lexmax]*/ # define cxmax 200 //size of code array /*最多的虚拟机代码数*/ /*符号*/ enum symbol{ nul, ident, number, plus, minus, times, slash, oddsym, eql, neq, //slash斜线 lss, leq, gtr, geq, lparen, //leq :less than or equal to; gtr: great than;lparen:left parenthesis rparen, comma, semicolon,period, becomes,//comma逗号semicolon分号period句号becomes赋值号 beginsym, endsym, ifsym, thensym, whilesym, writesym, readsym, dosym, callsym, constsym, varsym, procsym, }; #define symnum 32 /*-------------*/ enum object{ //object为三种标识符的类型 constant, variable, procedur, }; /*--------------*/ enum fct{ //fct类型分别标识类PCODE的各条指令 lit, opr, lod, sto, cal, inte, jmp, jpc, //书本P23 }; #define fctnum 8 /*--------------*/ struct instruction //指令 { enum fct f; //功能码 int l; //层次差 int a; //P23 }; FILE * fas; //输出名字表

交叉编译与调试!!!

交叉编译与调试方法 一、交叉编译 1. 建立工作目录 2. 编写源代码 3. 编写makefile文件 4. 编译应用程序 #arm-linux-gcc -g hello.c -o hello 5. 启动NSF,挂载共享文件目录 将光盘中的gdbserver与gdb程序拷贝到共享目录 二、调试步骤 1、在Target Board开启gdbserver 进入共享目录 #gdbserver :2345 hello (我的host-ip是192.168.0.178) gdbserver开始监听2345端口(你也可以设其他的值),然后启动hello,你会看到“Process test created:pid=88” 2、回到Host端 添加环境变量 #export PATH=$PATH:/home/cby/arm-gdb/bin(arm-linux-gdb的路径) 调试 #arm-linux-gdb hello 最后一行显示:This GDB was configured as “--host=i686-pc-linux-gnu,--target =arm-linux”... 说明此gdb在X86的Host上运行,但是调试目标是ARM代码。 (gdb)target remote :2345 (我的target-board-ip is 192.168.0.105) 注意:你的端口号必须与gdbserver开启的端口号一致,这样才能进行通信。 建立链接后,就可以进行调试了。调试在Host端,跟gdb调试方法相同。

注意的是要用“c”来执行命令,不能用“r”。因为程序已经在Target Board上面由gdbserver 启动了。结果输出是在Target Board端,用超级终端查看。 4. 交叉调试 (gdb)list (gdb)break func (gdb)break 22 (gdb)info br (gdb)c (这里不能用run) (gdb) n (gdb) p result (gdb) finish (跳出func 函数) (gdb) next (gdb) quit 建立连接后进行gdb 远程调试和gdb 本地调试方法相同

完整版编译原理名词解释

1. 源语言:书写源程序所使用的语言 2. 源程序:用程序设计语言书写的程序 3. 目标语言:计算机的机器指令。目标语言可以是机器语言,也可以是汇编语言, 或者是其他中间语言,但最终结果必是机器语言。 4. 目标程序:由机器指令构成的程序。目标程序是经过翻译程序加工后用目标语言 表示的程序。 5. 翻译程序:能够把某一种语言程序(源程序)改造成另一种语言程序(目标程序)将 源程序译成逻辑上等价的目标程序的程序。翻译程序有两种工作方式:编译和解释。 6. 编译程序:也称翻译程序 7. 解释程序:有些翻译程序在翻译过程中并不产生完整的目标程序,而是翻译一句, 解释执行一句,这样的称为解释程序。 8. 汇编程序:由汇编语言写成的程序 9. 词法分析:执行词法分析的程序成为词法分析器,词法分析依据的是语言构词规 则。词法分析器从文件读入源程序,由字符拼接单词。每当识别出一个单词,词法分析器就输出这个单词的内部码。 10. 语法分析:执行语法分析的程序叫做语法分析器。语法分析的任务就是根据语言 的规则,将词法分析器所提供的单词种别分成各类语法范畴。 11. 中间代码生成:中间代码产生有时称为语义分析,执行中间代码产生的程序称为 中间代码生成器。他的任务时按照语法分析器所识别出的语法范畴产生相应的中间代码,并建立符号表、常数表,等各种表格。 12. 目标代码生成:执行目标代码生成的程序称为目标代码生成器。他的任务是根据 中间代码和表格信息,确定各类数据在内存中的位置,选择合适的指令代码,将中间代码翻译成汇编语言或机器指令,这部分工作与计算机硬件有关。 13. 符号表:用于记录源程序中出现的标识符,一个标识符往往具有一系列的语义 值,她包括标识符的名称、种属、类型、值存放的地址等等。 14. 常数表:用于记录在源程序中出现的常数。 15. 编译程序前端:是由词法分析器、语法分析器和中间代码产生器组成的。她的特 点是依赖于被编译的源程序,输出结果用中间代码描述,和目标机器无关。16. 编译程序后端:是由目标代码生成器组成,他的特点是和源程序无关,以中间代 码形式的源程序为输入进行处理,输出结果依赖于目标机器。 17. 文本文件:文本文件的内容由94个图形字符‘!‘-' ~ '(33-126)和4个 控制字符换行(10)、回车(13)、空格(32)、TAB( 9)构成,文本文件又称为 ASCII码文件,扩展名通常为TXT,文件尾用控制字符EOF( 26)指示。 18. 二进制文件:由机器指令即二进制数构成,因二进制数可能是26 (文件结束控制 符),故文件尾用文件长度(文件的字节数)指示,扩展名通常为EX E。 19. 源代码(source code)—预处理器(preprocessor) —编译器(compiler) —汇编程序 (assembler)—目标代码(object code)—链接器(Linker) —可执行程序 (executables) 20. 编译程序的流程是: 源程序―》词法分析―》语法分析―》语义分析(中间代码产生)―》目标 代码生成-》目标程序

编译原理习题及答案

第一章 1、将编译程序分成若干个“遍”是为了。 a.提高程序的执行效率 b.使程序的结构更加清晰 c.利用有限的机器内存并提高机器的执行效率 d.利用有限的机器内存但降低了机器的执行效率 2、构造编译程序应掌握。 a.源程序b.目标语言 c.编译方法d.以上三项都是 3、变量应当。 a.持有左值b.持有右值 c.既持有左值又持有右值d.既不持有左值也不持有右值 4、编译程序绝大多数时间花在上。 a.出错处理b.词法分析 c.目标代码生成d.管理表格 5、不可能是目标代码。 a.汇编指令代码b.可重定位指令代码 c.绝对指令代码d.中间代码 6、使用可以定义一个程序的意义。 a.语义规则b.语法规则 c.产生规则d.词法规则 7、词法分析器的输入是。 a.单词符号串b.源程序 c.语法单位d.目标程序 8、中间代码生成时所遵循的是- 。 a.语法规则b.词法规则 c.语义规则d.等价变换规则 9、编译程序是对。 a.汇编程序的翻译b.高级语言程序的解释执行 c.机器语言的执行d.高级语言的翻译 10、语法分析应遵循。 a.语义规则b.语法规则 c.构词规则d.等价变换规则 二、多项选择题 1、编译程序各阶段的工作都涉及到。 a.语法分析b.表格管理c.出错处理 d.语义分析e.词法分析 2、编译程序工作时,通常有阶段。 a.词法分析b.语法分析c.中间代码生成 d.语义检查e.目标代码生成 三、填空题 1、解释程序和编译程序的区别在于。 2、编译过程通常可分为5个阶段,分别是、语法分析、代码优化和目标代码生成。 3、编译程序工作过程中,第一段输入是,最后阶段的输出为程序。 4、编译程序是指将程序翻译成程序的程序。 单选解答 1、将编译程序分成若干个“遍”是为了使编译程序的结构更加清晰,故选b。 2、构造编译程序应掌握源程序、目标语言及编译方法等三方面的知识,故选d。 3、对编译而言,变量既持有左值又持有右值,故选c。 4、编译程序打交道最多的就是各种表格,因此选d。 5、目标代码包括汇编指令代码、可重定位指令代码和绝对指令代码3种,因此不是目标代码的只能选d。 6、词法分析遵循的是构词规则,语法分析遵循的是语法规则,中间代码生成遵循的是语义规则,并且语义规则可以定义一个程序的意义。因此选a。 7、b 8、c 9、d 10、c 多选解答 1.b、c 2. a、b、c、e 填空解答

编译原理实验 简单词法分析(含源代码和实验结果)

附录一实验报告样式 《编译原理》实验报告 实验2 简单词法分析 姓名陈婷婷学号1009050121 班级计科1001班 时间:2012/4/5 地点:文波 同组人:无 指导教师:朱少林 实验目的 通过设计调试词法分析程序,实现从源程序中分出各种单词的方法;加深对课堂教学的理解;提高词法分析方法的实践能力。掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法;掌握词法分析的实现方法;上机调试编出的词法分析程序。 实验内容 ⑴掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法。 ⑵掌握词法分析的实现方法。 ⑶上机调试编出的词法分析程序。 ⑷为简单起见,假设编译语言为具有下特征的C_minus。该词法分析器要求至少能够识别C_minus中的以下几类单词: a.关键字:else if int return void while共6个,所有的关键字都是保留字,并且必须是小写; b.标识符:识别与C语言词法规定相一致的标识符,通过下列正则表达式定义:ID = letter (letter | digit)*; c.常数:NUM=(+ | - |ε)digit digit*(.digit digit* |ε)(e(+ | - |ε) digit digit* |ε),letter = a|..|z|A|..|Z|,digit = 0|..|9,包括整数,如123, -123, +123等;小数,如123.45, +123.45, -123.45;科学计数法表示的常数,如+1.23e3,-2.3e-9; d.专用符号:+ - * / < <= > >= == != = ; , ( ) [ ] { } /* */;

编译原理教程课后答案

1.2 计算机执行用高级语言编写的程序有哪些途径?它们之间的主要区别是什么? 【解答】计算机执行用高级语言编写的程序主要有两种途径:解释和编译。在解释方式下,翻译程序事先并不采用将高级语言程序全部翻译成机器代码程序,然后执行这个机器代码程序的方法,而是每读入一条源程序的语句,就将其解释(翻译)成对应其功能的机器代码语句串并执行,而所翻译的机器代码语句串在该语句执行后并不保留,最后再读入下一条源程序语句,并解释执行。这种方法是按源程序中语句的动态执行顺序逐句解释(翻译)执行的,如果一语句处于一循环体中,则每次循环执行到该语句时,都要将其翻译成机器代码后再执行。在编译方式下,高级语言程序的执行是分两步进行的:第一步首先将高级语言程序全部翻译成机器代码程序,第二步才是执行这个机器代码程序。因此,编译对源程序的处理是先翻译,后执行。从执行速度上看,编译型的高级语言比解释型的高级语言要快,但解释方式下的人机界面比编译型好,便于程序调试。这两种途径的主要区别在于:解释方式下不生成目标代码程序,而编译方式下生成目标代码程序。 1.3 请画出编译程序的总框图。如果你是一个编译程序的总设计师,设计编译程序时应当考虑哪些问题? 【解答】编译程序总框图如图所示。 作为一个编译程序的总设计师,首先要深刻理解被编 译的源语言其语法及语义;其次,要充分掌握目标指令的 功能及特点,如果目标语言是机器指令,还要搞清楚机器 的硬件结构以及操作系统的功能;第三,对编译的方法及 使用的软件工具也必须准确化。总之,总设计师在设计编 译程序时必须估量系统功能要求、硬件设备及软件工具等 诸因素对编译程序构造的影响等。 2.2 什么是扫描器?扫描器的功能是什么? 【解答】扫描器就是词法分析器,它接受输入的源程序,对源程序进行词法分析并识别出一个个单词符号,其输出结果是单词符号,供语法分析器使用。通常是把词法分析器作为一个子程序,每当词法分析器需要一个单词符号时就调用这个子程序。每次调用时,词法分析器就从输入串中识别出一个单词符号交给语法分析器。

C源程序调试方法

C源程序调试方法: 所谓源程序调试是指对程序的查错和排错,一般应经过以下几个步骤: 1进行静态检查 写好一个程序后,不要匆忙用编译器编译,应对写好的源程序进行人工检查,这一步是十分重要的,它能发现程序设计人员由于疏忽而造成的大多错误。为了减少编程错误,在编写程序中应力求做到以下几点: ①应当采用结构化程序方法编程,以增加可读性。 ②应尽可能多加注释,以帮助理解每段程序的作用。 ③在编写复杂的程序时,不要将全部的语句都写在main函数中,而要多利 用函数,用一个函数来实现单独的功能,既易于阅读也便于调试。各函数之间除了用参数传递数据这一渠道外,能够不用其他的渠道就尽量不用,数据间应尽量减少耦合的关系。 2、上机动态检查调试, 根据编译器提示的语法错误,提出编译器提示的全部错误(error)并一一改正,直到通过编译,生成下载文件或调试文件,还应该仔细检查编译器的警告(warning)信息,确认所有的警告信息并不会影响编译结果的正确性。有时,编译器的错误提示并非正确,而且出错的情况繁多且各种错误相互关联,因此要善于分析,找出真正的错误。 3、 Studio环境中进行硬件仿真或软件仿真。 测试的目的是为了测试软硬件能否在各处复杂的情况下正常工作,在测试时应当尽可能地将程序流程中的各分支和各种极限情况都测试一次,程序运行结果不对,大多属于逻辑错误,应将源程序与流程图仔细对照,是很容易发现错误的。 软件思想:本系统主要是用Mega 16主控单片机,控制液晶显示,输入键盘和电机的运行,Mega 16单片机根据键盘输入指令,运行相应的程序。当选择学习示教程序时,就是运用键盘控制电机的运行,然后记录电机运行的相关速度和最终的坐标到相应的寄存器,并在液晶显示器中显示学习示教程序运行状态,使用户更好的进行电机设置和了解电机的运行状态。

第2章 PL0编译程序的实现 完整课后习题答案+吕映芝编

第2章 PL/0编译程序的实现 第1题 PL/0语言允许过程嵌套定义和递归调用,试问它的编译程序如何解决运行时的存储管理。 答案: PL/0语言允许过程嵌套定义和递归调用,它的编译程序在运行时采用了栈式动态存储管理。(数组CODE存放的只读目标程序,它在运行时不改变。)运行时的数据区S是由解释程序定义的一维整型数组,解释执行时对数据空间S的管理遵循后进先出规则,当每个过程(包括主程序)被调用时,才分配数据空间,退出过程时,则所分配的数据空间被释放。应用动态链和静态链的方式分别解决递归调用和非局部变量的引用问题。 第2题 若PL/0编译程序运行时的存储分配策略采用栈式动态分配,并用动态链和静态链的方式分别解决递归调用和非局部变量的引用问题,试写出下列程序执行到赋值语句b∶=10时运行栈的布局示意图。 var x,y; procedure p; var a; procedure q; var b; begin (q) b∶=10; end (q); procedure s; var c,d; procedure r; var e,f; begin (r) call q; end (r); begin (s) call r; end (s); begin (p) call s;

end (p); begin (main) call p; end (main). 答案: 程序执行到赋值语句b∶=10时运行栈的布局示意图为: 第3题 写出题2中当程序编译到r的过程体时的名字表table的内容。 size name kind level/val adr 答案: 题2中当程序编译到r的过程体时的名字表table的内容为: name kind level/val adr size x variable 0 dx y variable 0 dx+1 p procedure 0 过程p的入口(待填) 5

相关主题
文本预览
相关文档 最新文档