三地址码简介

您所在的位置:网站首页 地址码转换 三地址码简介

三地址码简介

2024-07-11 14:11| 来源: 网络整理| 查看: 265

三地址码简介

三地址码(Three Address Code)是一种最常用的中间语言,编译器可以通过它来改进代码转换效率。每个三地址码指令,都可以被分解为一个四元组(4-tuple)的形式:(运算符,操作数1,操作数2,结果)。由于每个陈述都包含了三个变量,即每条指令最多有三个操作数,所以它被称为三地址码。

编译器

编译器(compiler),是一种计算机程序,它会将用某种编程语言写成的源代码(原始语言),转换成另一种编程语言(目标语言)。

它主要的目的是将便于人编写、阅读、维护的高级计算机语言所写作的源代码程序,翻译为计算机能解读、运行的低阶机器语言的程序,也就是可执行文件。编译器将原始程序(source program)作为输入,翻译产生使用目标语言(target language)的等价程序。源代码一般为高级语言(High-level language),如Pascal、C、C++、C# 、Java等,而目标语言则是汇编语言或目标机器的目标代码(Object code),有时也称作机器代码(Machine code)。

一个现代编译器的主要工作流程要通常要经过预处理、编译、汇编、链接等步骤。关于编译器的工作流程的介绍,可参考:从C源代码到可执行文件的四个过程:预处理、编译、汇编、链接

中间语言

中间语言(Intermediate language),有时也称为中间表示(Intermediate Rrepresentation,IR)在计算机科学中,是指一种应用于抽象机器(abstract machine)的编程语言,它设计的目的,是用来帮助我们分析计算机程序。这个术语源自于编译器,在编译器将源代码编译为目的码的过程中,会先将源代码转换为一个或多个的中间表述,以方便编译器进行最佳化,并最终产生出目的机器的机器语言。通常,中间语言的设计与一般的机器语言有三个不同之处:

每个指令代表仅有一个基本的操作。举例来说,在微处理器中出现的 shift-add 定址模式在中间语言不会出现。指令集内可能不会包含控制流程的资讯。暂存器可用的数量可能会很大,甚至没有限制。

最常见的中间语言表述形式,是三位址码(Three address code),常简称为 TAC 或 3AC。

这个术语也同时用来代称一些作为中间层的语言,有些高级语言不会输出为机器语言,它们仅会输出这种中间语言,而这些中间语言则会像一般语言一样,提交给编译器,编译为机器语言。这通常被用于让最佳化的过程更简单,也用于增进可移植性的能力,改进移植的方式则是利用中间语言的编译器,可以编译出许多中央处理器及操作系统可使用的机器码,例如C语言。中间语言的复杂度,通常介于高阶语言及低级语言之间,例如汇编语言。

四元式

四元式主要由四部分组成:OP,arg1,arg2,result,即(操作符,操作数1,操作数2,结果),

其中,OP是运算符,arg1,arg2分别是第一和第二个运算对象,result是编译程序为存放中间运算结果而引进的变量,常称为临时变量。当OP是一目运算时,常常将运算对象定义为arg1。

例如 X = a*b+c/d 的四元式序列:

(*, a, b, T1)(/, c, d, T2)(+, T1, T2, T3)(=, T3, -, X) 四元式出现的顺序和语法成份的计值顺序相一致。四元式之间的联系是通过临时变量实现的,这样易于调整和变动四元式。便于优化处理。 三地址码

三地址代码是四元式的另一种表示形式。每个三地址码指令,都可以被分解为一个四元式(4-tuple)。因为每个陈述都包含了三个变量,所以它被称为三地址码。

上面例子 X = a*b+c/d 的三地址序列:

t1=a*bt2=c/dt3=t1+t2X=t3 常用的三地址码(三地址码形式和四元组形式) 序号指令类型指令形式备注1赋值指令x = y op zx = op yop为运算符2复制指令x = y3条件跳转if x relop y goto nrelop为关系运算符4非条件跳转goto n跳转到地址n的指令5参数传递param x将x设置为参数6过程调用call p,np为过程的名字n为过程的参数的个数7过程返回return x8数组引用x=y[i]i为数组的偏移地址,而不是下标9数组赋值x[i]=y10地址及指针操作x=&yx=*y *x=y

将上表的三地址指令用四元式表示

x = y op z( op , y , z , x)x = op y( op , y , _ , x)x = y( = , y , _ , x)if x relop y goto n( relop , x , y , n)goto n( goto , _ , _ , n)param x( param , _ , _ , x)call p,n( call , p , n , _)return x( return , _ , _ , x)x=y[i]( =[] , y , i , x) ps: y为基地址,i为偏移地址x[i]=y( []= , y , x , i)x=&y( & , y , _ , x)x=*y( =* , y , _ , x)*x=y( *= , y , _ , x)

每一个指令只有一个操作符,那么只完成一个动作,这样看来,三地址指令序列唯一确定了运算完成的顺序。

中间代码生成的例子 while a


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3