编译研究(3)——同名变量定义
2007-07-01 22:51
357 查看
今天在处理变量时发现了一个问题:对于不同函数中定义的同名变量,在源代码中,我原来只是简单根据变量名称进行区分,由于作用范围不同,所在符号表不同,因为虽然同名但互不影响;但这样的方法用在中间代码中就会出问题。例如中间代码使用同一个列表处理所有变量,并只是简单根据变量名称来在这个列表中索引变量的值,因此同名变量会重叠,并相互影响。
为此参考了vc生成的汇编代码,发现它对变量的引用都是把变量名称和基址指针联合起来表识一个变量,例如有以下c/++代码:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
int n=1 ;
则它的汇编代码会是这样的:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
_TEXT SEGMENT
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
_n$ = -4
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
mov DWORD PTR _n$[ebp], 1
可见它是利用变量名称和基址指针指向的实时值联合起来引用一个变量,如此一来就能够很好解决变量名称重叠的问题。
鉴于我的虚拟机种内存模型还很简单,不能用这么复杂的寄存器来表示变量,因此我暂时根据变量所在函数的序号和变量名称来引用变量:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
n=1 ;
则中间代码是:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
mv n?1, 1
表示这里引用的是1号函数中定义的n。
另外,如果考虑在不同嵌套层次定义同名变量,方法也类似。如下代码所示:
在生成代码时,只要根据作用域来加以区分即可。例如函数序号为0,函数入口处作用域编号为0,第一个嵌套作用域编号加1,依次递增。上述代码中,第一个n在中间代码中表示为 n?0?0 ,第二个为n?0?1 ,第三个为n?0?2 等等,如此类推。
为此参考了vc生成的汇编代码,发现它对变量的引用都是把变量名称和基址指针联合起来表识一个变量,例如有以下c/++代码:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
int n=1 ;
则它的汇编代码会是这样的:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
_TEXT SEGMENT
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
_n$ = -4
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
mov DWORD PTR _n$[ebp], 1
可见它是利用变量名称和基址指针指向的实时值联合起来引用一个变量,如此一来就能够很好解决变量名称重叠的问题。
鉴于我的虚拟机种内存模型还很简单,不能用这么复杂的寄存器来表示变量,因此我暂时根据变量所在函数的序号和变量名称来引用变量:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
n=1 ;
则中间代码是:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
mv n?1, 1
表示这里引用的是1号函数中定义的n。
另外,如果考虑在不同嵌套层次定义同名变量,方法也类似。如下代码所示:
![]()
$不同嵌套作用域的同名变量定义
![]()
_proc test() :
![]()
int n=0 ;
![]()
if(n==0)
int n=1 ;
loop(1)
int n = 21 ;
endl
n = n+1 ;
endi
n = 1 ;
![]()
_endp
在生成代码时,只要根据作用域来加以区分即可。例如函数序号为0,函数入口处作用域编号为0,第一个嵌套作用域编号加1,依次递增。上述代码中,第一个n在中间代码中表示为 n?0?0 ,第二个为n?0?1 ,第三个为n?0?2 等等,如此类推。
相关文章推荐
- 编译研究(4)——变量定义再讨论
- C++继承时子类定义同名成员变量时的调用继承函数的问题
- 【linux】内核make编译链接相关变量定义
- 第三篇:VS2012中,调用opencv库,在程序中定义了变量,编译没有问题,运行时会报错“变量使用没有定义”
- 变量的声明和定义,从C到编译原理到C++,再到Java
- cocos2dx+vs2013生成的安卓项目,编译时提示环境变量 ANDROID SDK_ROOT 没有定义
- 【VBA研究】变量定义的类型和实际赋值类型
- 编译vs2015 有个变量找不到定义,
- 编译研究(2)——关于函数重定义的处理
- 头文件、声明、定义以及条件编译为什么不能定义变量的个人理解
- VS2008编译C代码时会检查变量定义的位置,可以改为编译为C++代码
- 两个文件定义了同名的变量,会是同一个变量吗?
- C++编译器在编译程序时会自动定义的预处理器(类似于全局变量)
- PHP函数调用及循环体内定义大型变量效率的研究
- solidity定义变量出现无法编译错误。
- 编译原理程序设计实践(二) 全局变量定义
- C++继承时子类定义同名成员变量时的调用继承函数的问题
- [编译相关]系列5:Makefile中的变量定义
- Map 定义变量时编译的问题
- 【linux】内核make编译链接相关变量定义