变量
变量
变量在内存中的位置和访问方式
位置
在属性为可读写的数据节中
访问方式
栈内存:ebp-- ebp++
堆内存:间接访问
全局变量存储区:使用offset寻址
常量区:使用offset寻址
全局变量
位置:所在地址为数据区
生命周期:与所在模块一致,在程序执行前都已经存在
访问方式:使用立即数间接访问
在内存中的地址:先定义是低地址,后定义是高地址
作用域:进程作用域,在整个进程中都能够访问这个全局变量
局部变量
位置:所在地址为栈区
生命周期:与所在函数作用域一致(对于有{}的划分块,生命周期与所在函数作用域一致,只是编译器不允许块外代码对其访问)
访问方式:使用ebp或esp间接访问
在内存中的地址:先定义是高地址,后定义是低地址
作用域:函数作用域,在函数内可以访问到;在“{ }”语句块内定义的变量,属于块作用域,只能在定义变量的“{ }”块内访问
全局静态变量
位置:所在地址为数据区,生命周期与所在模块一致,在程序执行前都已经存在
生命周期:整个文件
访问方式:使用立即数间接访问
在内存中的地址:先定义是低地址,后定义是高地址
作用域:文件作用域,在当前源码文件内可以访问到
限制:只能在本文件内使用,等价于编译器限制外部源码文件访问的全局变量,即全局变量可以跨cpp文件,全局静态变量不行
局部静态变量
位置:在进入作用域之前就已经存在,生命周期和全局变量相同,在程序执行前都已经存在
生命周期:整个文件
作用域:{}块
寻址:使用绝对寻址offset的寻址方式;立即数即为offset的绝对地址,绝对地址的间接访问
注意
对于大型编译器,如果只声明变量而不使用的话在IDA中不会显示出来
void Sub_2()
{
int i = 0;
for (i=0;i<3;i++)
{
int v1 = 0;
v1++;
static int v2 = 0;
v2++;
_tprintf(_T("%d %d\r\n"), v1, v2);
/*
00F318C7 C7 45 EC 00 00 00 00 mov dword ptr [ebp-14h],0 //注意v1在函数块内进行赋值
00F318CE 8B 45 EC mov eax,dword ptr [ebp-14h]
00F318D1 83 C0 01 add eax,1
00F318D4 89 45 EC mov dword ptr [ebp-14h],eax
00F318D7 A1 04 A2 F3 00 mov eax,dword ptr [v2 (0F3A204h)] //v2的赋值在函数块之前
00F318DC 83 C0 01 add eax,1
00F318DF A3 04 A2 F3 00 mov dword ptr [v2 (0F3A204h)],eax
*/
}
}