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.
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.
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_header
And _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.