静态变量底层实现

静态变量底层实现

静态变量有局部静态变量(作用域内的静态变量),全局静态变量,然而他们的实现和全局变量是一样的,而局部静态变量只能在作用域访问是C语言的优化。

局部静态变量不会随作用域结束而销毁,并且在未进入作用域之前就已经存在,其生命周期也与全局变量相同。局部静态变量和全局变量都保存在执行文件中的数据区中。

局部静态变量会预先被作为全局变量处理,而它的初始化部分,只是在做赋值操作而已。

在C++语法中局部静态变量只能被初始化一次,编译器的内部实现如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void Static(int nNum)
{
static int g_nNum = nNum;
xor eax,eax
mov al,byte ptr['Static'::'2'::$$1 (004257cc)]
and eax,1
test eax,eax
jne pp
mov cl,byte ptr['Static'::'2'::$$1 (004257cc)]
or cl,1
mov byte ptr['Static'::'2'::$$1 (004257cc)], cl
mov edx,[ebp + 8]
mov [_sbh_sizeHeaderList+4 (004257c8)],edx
pp:
printf("%d", g_nNum);
}

上述代码首先从004257cc处取出1字节内容进行判断,这个byte的内容实际上就是局部静态变量初始状态的一个标志,这个标志占1字节,通过位运算,将标志的一位置1,而1个字节占8位,so这个标志可以同时表示8个局部静态变量的初始状态。

标志坐在的内存地址在最先定义的局部静态变量地址的附近,如最先定义的整型局部静态变量在地址0x004257C0处,那么标记位地址通常在0x004257C4或0x004257BC处。当同一作用域内超过8个局部静态变量时,下一个标记位将会在第9个定义的局部静态变量地址附近。

当局部静态变量为数组时,那么只检查数组的第1个字节是否进行过初始化,其他位将不进行检查。

1571159941863

Author: YuanBi
Link: https://www.basicbit.cn/2018/10/20/2018-10-20-静态变量底层实现/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.