㈠ 关于编译原理的问题
1.当然是机器语言了,如果是汇编指令,那还得编译一次!能运行的程序都是机器语言,只有机器语言才能控制CPU,NET或Java这些中间语言,程序在运行时会被CLR或JVM快速编译成机器语言,因此这些程序速度上有损失。
高级语言源代码(文本)-通过编译器(compiler)-程序(二进制机器语言)
汇编代码(文本)-通过汇编器(assembler)-程序(二进制语言)
看到这里,你可能会想那汇编语言到底有什么用呢,编译器完全能代替汇编啊?
(1).编译器是通过高级语言(c,c++)转到机器语言的。转换过的机器语言受限与高级语言,效率和功能上都有限制。比如c不等过分操作内存。但通过汇编器转化过来的机器语言,效率高,且用汇编语言,直接和CPU对话!
(2).汇编可以反汇编(逆向编译),而这里高级语言没有发言权,就是:
程序(二进制机器语言)-通过反汇编器(compiler)-可转化为汇编代码(文本)
但永远不能转化为高级语言的源代码,。
以上两点汇编存在的重要性。
2。当然是说移植源代码。windows用x86机器语言,苹果用powerPC机器语言,windows程序当然不能运行在苹果机上,因为程序其实就是一串机器语言!但windows上有c的编译器(vc++),苹果机上也有c编译器(gcc),因此同一个c的源代码,当然就可以通过不同平台的同一种编译器实现平台移植。
3.当然是NASM,我看的所有书都首先说NASM,他是开源的,就像Linux一样,很受欢迎,还有MASN是微软的,borland的也有汇编器,不过都不常见了。
4.这跟CPU有关,一般32位x86兼容的cpu有许多寄存器,多数是32位的,也有16位的。比如CS,ES,DS这些segment寄存器一直是16位的。
5.优势太多了,这和32位和16位存在的优势一样,16位电脑最大内存1MB,寄存器都是16位的。32位,最大内存可以有4GB,整整是16位的4096倍啊!16位多渺小啊,同理64位基本上也可以蔑视32位,64内存最大内存用TB来衡量,寄存器多数是64位!地址总线也是64位。64对32位没有什么优势劣势可言,64位完全就是32位的下一代。
㈡ 编译原理的基本概念
编译器 是将汇编或高级计算机语言翻译为二进制机器语言代码的计算机程序。编译器将源程序(source language) 编写的程序作为输入,翻译产生目标语言(target language )机器代码的等价程序。通常地,源程序为高级语言(high-level language ),像C或C + +、汉语语言程序等,而目标则是机器语言的目标代码 (object code,有时也称作机器代码(machine code )),也就是可以在计算机硬件中运行的机器代码软件程序。这一过程可以表示为:
源程序→编译器 →目标机器代码程序
㈢ C语言编译原理是什么
编译共分为四个阶段:预处理阶段、编译阶段、汇编阶段、链接阶段。
1、预处理阶段:
主要工作是将头文件插入到所写的代码中,生成扩展名为“.i”的文件替换原来的扩展名为“.c”的文件,但是原来的文件仍然保留,只是执行过程中的实际文件发生了改变。(这里所说的替换并不是指原来的文件被删除)
2、汇编阶段:
插入汇编语言程序,将代码翻译成汇编语言。编译器首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,编译器把代码翻译成汇编语言,同时将扩展名为“.i”的文件翻译成扩展名为“.s”的文件。
3、编译阶段:
将汇编语言翻译成机器语言指令,并将指令打包封存成可重定位目标程序的格式,将扩展名为“.s”的文件翻译成扩展名为“.o”的二进制文件。
4、链接阶段:
在示例代码中,改代码文件调用了标准库中printf函数。而printf函数的实际存储位置是一个单独编译的目标文件(编译的结果也是扩展名为“.o”的文件),所以此时主函数调用的时候,需要将该文件(即printf函数所在的编译文件)与hello world文件整合到一起,此时链接器就可以大显神通了,将两个文件合并后生成一个可执行目标文件。
㈣ 编译原理的相关程序
解释程序(interpreter):解释程序是如同编译器的一种语言翻译程序。它与编译器的不同之处在于:它立即执行源程序而不是生成在翻译完成之后才执行的目标代码。从原理上讲,任何程序设计语言都可被解释或被编译,但是根据所使用的语言和翻译情况,很可能会选用解释程序而不用编译器。例如, 我们经常解释BASIC语言而不是去编译它。类似地,诸如LISP 的函数语言也常常是被解释的。
解释程序也经常用于教育和软件的开发,此处的程序很有可能被翻译若干次。而另一方面,当执行的速度是最为重要的因素时就使用编译器,这是因为被编译的目标代码比被解释的源代码要快得多,有时要快10倍或更多。但是,解释程序具有许多与编译器共享的操作,而两者之间也有一些混合之处。 代码生成(code generator):代码生成器得到中间代码(IR),并生成目标机器的代码。正是在编译的这个阶段中,目标机器的特性成为了主要因素。当它存在于目标机器时,使用指令不仅是必须的而且数据的形式表示也起着重要的作用。例如,整型数据类型的变量和浮点数据类型的变量在存储器中所占的字节数或字数也很重要。在上面的示例中,现在必须决定怎样存储整型数来为数组索引生成代码。例如,下面是所给表达式的一个可能的样本代码序列(在假设的汇编语言中):
M O V R0,index ;;
value of index -> R0 M U L R0,2 ;;
double value in R0 M O V R1,&a ;;
address of a -> R1 A D D R1,R0 ;;
add R0 to R1 M O V *R1,6 ;;
constant 6 -> address in R1
在以上代码中,为编址模式使用了一个类似C的协定,因此& a是a的地址(也就是数组的基地址),* R1则意味着间接寄存器地址(因此最后一条指令将值6存放在R1包含的地址中)。这个代码还假设机器执行字节编址,并且整型数占据存储器的两个字节(所以在第2条指令中用2作为乘数)。 目标代码(target code optimizer ):在这个阶段中,编译器尝试着改进由代码生成器生成的目标代码。这种改进包括选择编址模式以提高性能、将速度慢的指令更换成速度快的,以及删除多余的操作。在上面给出的样本目标代码中,还可以做许多更改:在第2条指令中,利用移位指令替代乘法(通常地,乘法很费时间),还可以使用更有效的编址模式(例如用索引地址来执行数组 存储)。使用了这两种优化后,目标代码就变成:
MOV R0,index ;;
value of index -> R0 SHL R0 ;;
double value in R0 MOV &a[R0],6 ;;
constant 6 -> address a + R0
到这里就是编译原理的简要描述,但还应特别强调编译器在其结构细节上差别很大。
㈤ 编译原理:Codeblocks的源码学习
??iihgujjjjjjjjjj
㈥ 急求:编译原理判断文法类型的C语言源代码!!!!!!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/**//*全局变量定义*/
char inputString[10]; /**//*用来存储用户输入的字符串,最长为20个字符*/
char stack[10]; /**//*用来进行语法分析的栈结构*/
int base=0; /**//*栈底指针*/
int top=1; /**//*栈顶指针*/
char VT[4]={'a','d','b','e'}; /**//*用来存放5个终结符*/
char chanShengShi[10]; /**//*用来存放预测分析表M[A,a]中的一条产生式*/
int firstCharIntex=0; /**//*如果a匹配产生式,则每次firstCharIntex 自增 1 */
/**//*firstCharIntex用来存放用户输入串的第一个元素的下标*/
/**//*自定义函数声明*/
char pop() ; /**//*弹出栈顶元素*/
int push(char) ; /**//*向栈内添加一个元素,成功返回1,若栈已满则返回0*/
int search(char temp) ; /**//*查找非终结符集合VT中是否存在变量temp,存在返回1,不存在返回0*/
int M(char A, char a) ; /**//* 若预测分析表M[A,a]中存在产生式,
则将该产生式赋给字符数组chanShengShi[10],并返回 1,
若M[A,a]中无定义产生式则返回 0
*/
void init() ; /**//*初始化数组inputString[10] 、栈 stack[10] 和 chanShengShi[10]*/
int yuCeFenXi() ; /**//* 进行输入串的预测分析的主功能函数,
若输入串满足文法则返回 1,不满足则返回0
*/
void printStack(); /**//*打印栈内元素 */
void printinputString(); /**//*打印用户输入串 */
/**//*进入主函数*/
void main()
{
system("cls");
yuCeFenXi(); /**//*调用语法预测分析函数*/
system("pause");
}
/**//*函数的定义*/
int yuCeFenXi()
{
char X; /**//*X变量存储每次弹出的栈顶元素*/
char a; /**//*a变量存储用户输入串的第一个元素*/
int i;
int counter=1; /**//*该变量记录语法分析的步骤数*/
init(); /**//*初始化数组*/
printf("wen fa : \n"); /**//*输出文法做为提示*/
printf("S -> aH \n");
printf("H -> aMd | d \n");
printf("M -> Ab | \n");
printf("A -> aM | e \n");
printf("\ninput string ,'#' is a end sign !!(aaabd#) \n"); /**//*提示用户输入将要测试的字符串*/
scanf("%s",inputString);
push('#');
push('S');
printf("\nCounter-----Stack---------------Input string \n"); /**//*输出结果提示语句*/
while(1) /**//*while循环为语法分析主功能语句块*/
{
printf(" ");
printf(" %d",counter); /**//*输出分析步骤数*/
printf(" "); /**//*输出格式控制语句*/
printStack(); /**//*输出当前栈内所有元素*/
X=pop(); /**//*弹出栈顶元素赋给变量X*/
printinputString(); /**//*输出当前用户输入的字符串*/
if( search(X)==0 ) /**//*在终结符集合VT中查找变量X的值,存在返回 1,否则返回 0*/
{
if(X == '#') /**//*栈已经弹空,语法分析结果正确,返回 1*/
{
printf("success \n"); /**//*语法分析结束,输入字符串符合文法定义*/
return 1;
}
else
{
a = inputString[firstCharIntex];
if( M(X,a)==1 ) /**//*查看预测分析表M[A,a]是否存在产生式,存在返回1,不存在返回0*/
{
for(i=0;i<10;i++) /**//* '$'为产生式的结束符,for循环找出该产生式的最后一个元素的下标*/
{
if( chanShengShi[i]=='$' ) break;
}
i-- ; /**//*因为 '$' 不是产生式,只是一个产生式的结束标志,所以i自减1*/
while(i>=0)
{
push( chanShengShi[i] ); /**//*将当前产生式逆序压入栈内*/
i-- ;
}
}
else
{
printf(" error(1) !!\n"); /**//*若预测分析表M[A,a]不存在产生式,说明语法错误*/
return 0;
}
}
}
else /**//*说明X为终结符*/
{
if( X==inputString[firstCharIntex] ) /**//*如果X等于a,说明a匹配*/
{
firstCharIntex++; /**//*输入串的第一个元素被约去,下一个元素成为新的头元素*/
}
else
{
printf(" error(2) !! \n");
return 0;
}
}
counter++;
}
}
void init()
{
int i;
for(i=0;i<10;i++)
{
inputString[i]=NULL; /**//*初始化数组inputString[10] */
stack[i]=NULL; /**//*初始化栈stack[10] */
chanShengShi[i]=NULL; /**//*初始化数组chanShengShi[10]*/
}
}
int M(char A, char a) /**//*文法定义因实际情况而定,该文法为课本例题的文法*/
{ /**//*该函数模拟预测分析表中的二维数组 */
if( A=='S'&& a=='a' ) { strcpy(&chanShengShi[0],"aH$"); return 1; }
if( A=='H'&& a=='a' ) { strcpy(&chanShengShi[0],"aMd$"); return 1; }
if( A=='H'&& a=='d' ) { strcpy(&chanShengShi[0],"d$"); return 1; }
if( A=='M'&& a=='a' ) { strcpy(&chanShengShi[0],"Ab$"); return 1; }
if( A=='M'&& a=='d' ) { strcpy(&chanShengShi[0],"$"); return 1; }
if( A=='M'&& a=='b' ) { strcpy(&chanShengShi[0],"$"); return 1; }
if( A=='M'&& a=='e' ) { strcpy(&chanShengShi[0],"Ab$"); return 1; }
if( A=='A'&& a=='a' ) { strcpy(&chanShengShi[0],"aM$"); return 1; }
if( A=='A'&& a=='e' ) { strcpy(&chanShengShi[0],"e$"); return 1; }
else return 0; /**//*没有定义产生式则返回0*/
}
char pop() /**//*弹出栈顶元素,用topChar返回*/
{
char topChar;
topChar=stack[--top];
return topChar;
}
int push(char ch)
{
if( top>9 )
{
printf(" error : stack overflow "); /**//*栈空间溢出*/
return 0;
}
else
{
stack[top]=ch; /**//*给栈顶空间赋值*/
top++;
return 1;
}
}
int search(char temp)
{
int i,flag=0; /**//*flag变量做为标志,若找到temp则赋1,否则赋0*/
for(i=0;i<4;i++)
{
if( temp==VT[i] ) /**//*终结符集合中存在temp*/
{
flag=1;
break;
}
}
if(flag==1) return 1; /**//*flag==1说明已找到等于temp的元素*/
else return 0;
}
void printStack() /**//*输出栈内内容*/
{
int temp;
for(temp=1;temp<top;temp++)
{
printf("%c",stack[temp]);
}
}
void printinputString() /**//*输出用户输入的字符串*/
{
int temp=firstCharIntex ;
printf(" "); /**//*该句控制输出格式*/
do{
printf("%c",inputString[temp]);
temp++;
}while(inputString[temp-1]!='#');
printf(" \n");
}