C++源代码:
#include<stdio.h> int global=5; void test(int x); int main() { int i; for(i=0;i<global;i++) { test(i); } return 0; } void test(int x) { static int y1=x; static int y2=x; }生成的汇编代码:
Dump of assembler code for function main: 0x004012f0 <main+0>: push %ebp 0x004012f1 <main+1>: mov %esp,%ebp 0x004012f3 <main+3>: sub $0x18,%esp 0x004012f6 <main+6>: and $0xfffffff0,%esp 0x004012f9 <main+9>: mov $0x0,%eax 0x004012fe <main+14>: add $0xf,%eax 0x00401301 <main+17>: add $0xf,%eax 0x00401304 <main+20>: shr $0x4,%eax 0x00401307 <main+23>: shl $0x4,%eax 0x0040130a <main+26>: mov %eax,-0x8(%ebp) 0x0040130d <main+29>: mov -0x8(%ebp),%eax 0x00401310 <main+32>: call 0x401874 <_alloca> 0x00401315 <main+37>: call 0x4013f4 <__main> 0x0040131a <main+42>: movl $0x0,-0x4(%ebp) 0x00401321 <main+49>: mov -0x4(%ebp),%eax 0x00401324 <main+52>: cmp 0x402000,%eax 0x0040132a <main+58>: jge 0x40133e <main+78> 0x0040132c <main+60>: mov -0x4(%ebp),%eax 0x0040132f <main+63>: mov %eax,(%esp) 0x00401332 <main+66>: call 0x401346 <_Z4testi> 0x00401337 <main+71>: lea -0x4(%ebp),%eax 0x0040133a <main+74>: incl (%eax) 0x0040133c <main+76>: jmp 0x401321 <main+49> 0x0040133e <main+78>: mov $0x0,%eax 0x00401343 <main+83>: leave 0x00401344 <main+84>: ret End of assembler dump. (gdb)
Dump of assembler code for function _Z4testi: 0x00401346 <_Z4testi+0>: push %ebp 0x00401347 <_Z4testi+1>: mov %esp,%ebp 0x00401349 <_Z4testi+3>: cmpb $0x0,0x404010 0x00401350 <_Z4testi+10>: jne 0x401361 <_Z4testi+27> 0x00401352 <_Z4testi+12>: mov 0x8(%ebp),%eax 0x00401355 <_Z4testi+15>: mov %eax,0x404030 0x0040135a <_Z4testi+20>: movb $0x1,0x404010 0x00401361 <_Z4testi+27>: cmpb $0x0,0x404020 0x00401368 <_Z4testi+34>: jne 0x401379 <_Z4testi+51> 0x0040136a <_Z4testi+36>: mov 0x8(%ebp),%eax 0x0040136d <_Z4testi+39>: mov %eax,0x404040 0x00401372 <_Z4testi+44>: movb $0x1,0x404020 0x00401379 <_Z4testi+51>: pop %ebp 0x0040137a <_Z4testi+52>: ret End of assembler dump. (gdb)
cmp 0x402000,%eax观察这句代码,访问全局变量与访问常量类似,都是通过立即数来访问。由于全局变量在编译时已经确定了具体的地址,因此编译器可以计算出一个具体的地址值。
movb $0x1,0x404010
cmpb $0x0,0x404010观察这句代码,初始化局部静态变量时使用0x404010作为标志位,标记为1后,以后再想改变时,要和0比较,不等于就跳过了,这就是局部静态变量作用的原理。
全局静态变量和全局变量在内存结构和访问原理上都是一样的,相当于全局静态变量等价于编译器限制外部文件访问的全局变量。