Local static variable is initialized only once is how to achieve?

Static variables can be divided into global static variables, static and local variables, first is that the global bar. The difference between global static and global variables are not large, but the global static variables can only be used in the current file, and there is no difference between the two in the disassembly, you can only use in the current file, but is made by the compiler limit. Local static variables will be some special, it will not disappear with the end of the scope, went into effect in not before existed. Local static and global variables are stored in the data area of ​​a binary file, and restrictions in the code, but the compiler limit it.

So when a function is frequently called local static variables, C ++ syntax specified local static variable is initialized only once, then the compiler is how to do it.

Look at the code:

void ShowStatic(int nNum)
{
    static int gnNumber = nNum;
    printf("%d\n", gnNumber);
}

void main()
{
    ShowStatic(99);
}

Assembly code:

00E51738  mov         eax,dword ptr ds:[00E5A148h] 
00E5173D  and         eax,1 
00E51740  jne         ShowStatic+47h (0E51757h) 
00E51742  mov         eax,dword ptr ds:[00E5A148h] 
00E51747  or          eax,1 
00E5174A  mov         dword ptr ds:[00E5A148h],eax 
00E5174F  mov         eax,dword ptr [nNum] 
00E51752  mov         dword ptr [gnNumber (0E5A144h)],eax

As can be seen, the assignment of the static variable assignments a lot more steps than the average variable, we have to analyze.

First, save the mark local static variables in the address 00E5A148h, this flag is 1 byte. By the bit operation, the flag in a data set, determines whether the local static variables initialized. And this sign can save the initial state of eight local static variables at the same time.

This flag generally occurs near the local static variables defined in the first example of this embodiment should appear in the local variables or 00E5A14Ch in 00E5A144h. When the same scope than the 8 static local variable, except that now the next nearby will address local static variables defined in the first nine markers. Now look at the assembly code above is very clear:

00E51738  mov         eax,dword ptr ds:[00E5A148h] 
00E5173D  and         eax,1 
00E51740  jne         ShowStatic+47h (0E51757h)

Whether off has been initialized, if it has been initialized Jump to printf output content, or do not jump to continue.

00E51742  mov         eax,dword ptr ds:[00E5A148h] 
00E51747  or          eax,1 
00E5174A  mov         dword ptr ds:[00E5A148h],eax 
00E5174F  mov         eax,dword ptr [nNum] 
00E51752  mov         dword ptr [gnNumber (0E5A144h)],eax

Without initialization, the flag is set to 1, and initialize gnNumber.

There is such a problem, the compiler so that other scopes of local static variables are not visible, this is how to do? During compilation, the compiler will variables, functions, and so were crushed name, that is, static variables are renamed.

We observed generated after the end of the next compile obj file, search for static variables in the file name (This article open obj file HxD software), the search results as shown below:

 

 

After crushing the name, the original name plus added some extra information, the scope, type and so on. Like C ++ overloading is also the name of crushing principle.

The following compilation is the result of compiled C ++ 11, and obviously some gaps above:
static int gnNumber = nNum;
00C11818  mov         eax,dword ptr [_tls_index (0C1B190h)] 
00C1181D  mov         ecx,dword ptr fs:[2Ch] 
00C11824  mov         edx,dword ptr [ecx+eax*4] 
00C11827  mov         eax,dword ptr ds:[00C1B150h] 
00C1182C  cmp         eax,dword ptr [edx+104h] 
00C11832  jle         ShowStatic+6Fh (0C1185Fh) 
00C11834  push        0C1B150h 
00C11839  call        __Init_thread_header (0C110DCh) 
00C1183E  add         esp,4 
00C11841  cmp         dword ptr ds:[0C1B150h],0FFFFFFFFh 
00C11848  jne         ShowStatic+6Fh (0C1185Fh) 
00C1184A  mov         eax,dword ptr [nNum] 
00C1184D  mov         dword ptr [gnNumber (0C1B14Ch)],eax 
00C11852  push        0C1B150h 
00C11857  call        __Init_thread_footer (0C11177h) 
00C1185C  add         esp,4

The first three lines of code:

00C11818  mov         eax,dword ptr [_tls_index (0C1B190h)] 
00C1181D  mov         ecx,dword ptr fs:[2Ch] 
00C11824  mov         edx,dword ptr [ecx+eax*4]

TLS? How more than two functions? __Init_thread_headerAnd _Init_thread_footer。these two functions are used to initialize the thread to ensure the safety of local static objects. But still the same mutex local variable, but is encapsulated into the aforementioned two functions.

Guess you like

Origin www.cnblogs.com/yilang/p/12106236.html