两年前写的,欢迎大家吐槽!
转载请注明出处。
1. 全局变量和局部变量的区别
具有初始值的全局变量在源代码链接时就被写入所创建的PE文件,当该文件被执行时操作系统分析各个节中的数据填入对应的内存地址中,这时全局变量就已经存在了,等PE文件的分析和加载工作完成之后才执行入口点的代码。所以全局变量不受作用域的影响,程序的任何位置都可以访问。下面就来具体讲述不同点。
全局变量和常量类似都是被写入文件中,因此生命周期和模块相同,而其与局部变量最大的不同之处便是生命周期。按照上面所说,全局变量在执行第一条代码前便存在,知道程序退出销毁,而局部变量的生命周期则仅限于函数作用域内,超出作用域便会由栈平衡操作来释放其空间。在访问方式上,局部变量是通过栈指针来访问的,但是全部变量不在栈中,就无法用栈指针访问。下面就来说说是如何访问全局变量的。还是先看一个例子(Debug版本):
19: void main()
20: {
;栈空间分配和初始化保存环境略
21: scanf("%d", &g_nVariableType);
0042B45E push offset g_nVariableType (48C000h) ;通过直接寻址来直接访问全局变量
0042B463 push offset string "%d, %d" (47CC80h)
0042B468 call @ILT+3005(_scanf) (429BC2h)
0042B46D add esp,8
22: printf("%d\r\n",g_nVariableType);
0042B470 mov eax,dword ptr [g_nVariableType (48C000h)] ;此处同上
0042B475 push eax
0042B476 push offset string "%d %d\r\n" (47CC74h)
0042B47B call @ILT+4085(_printf) (429FFAh)
0042B480 add esp,8
23: };栈平衡操作及环境恢复略
可以很清楚的看到全局变量是用直接寻址来访问的,这是因为全局变量存储在文件中,加载至内存时也会随着文件加载到内存的固定偏移位置,所以编译器可以决定其用直接寻址找到它。而局部变量是存储在栈中的,无法确定其地址,故无法使用直接寻址方式,应采用相对寻址。下面再来看一下多个全局变量的情况(Debug版本):
19: void main()
20: { ;栈空间分配和初始化保存环境略
21: /*scanf("%d", &g_nVariableType);
22: printf("%d\r\n",g_nVariableType);*/
23: //全局变量与局部变量对比
24: intnOne = 1;
0042D8EE mov [ebp-8], 1 ;局部变量的定义
25: intnTwo = 2;