A Preliminary Study on the implementation principle of the static and const Compilers

Source: Internet
Author: User

Author: evilknight
Source: evil baboons Information Security Team (www.eviloctal.com)
Compiling environment: WinXP sp2 + VC6.0 SP 6

For many C/C ++ beginners, they often know that static variables are only initialized once. For const variables, they only know that their values cannot be modified, however, I do not know all about its implementation. Here I use VC6.0 SP6 as a platform to uncover its compiler implementation principle.
Let's take a look at a program: Reference:
# Include <iostream. h>
Void fun (int I)
{
Static int n = I;
Int * p = & n;
Cout <n <endl;
++ N;
//
// Wait until we write code here to make static int n
// This function is initialized every time.
//
}
Int main (void)
{
For (int I (10); I> 0; -- I)
{
Fun (I );
}
Return 0;
} The output result of the program is: Reference:
10
11
12
13
14
15
16
17
18
19 now let's debug and see how the compiler is implemented:
We set a breakpoint in the first line of the fun function. Static int n = I; in the row, press F5.
Press Alt + 6 to open Memory. Press F10 for one-step execution. When p has a value, we drag the value to the Memory window and it will go to the Memory address where n is located, but static has been initialized, we don't know what operations the compiler has done to him. Now let's start debugging again. Generally, the memory address of n will not change, but it is still there.
Here I will take my address as an example: Reference:
0042E058 00 00 00 ....
0042E05C 00 00 00 00... // The memory address in the middle is n.
0042E060 00 00 00 00... we execute a single statement (static int n = I;) by pressing F10 reference:
0042E058 01 00 00 00 ....
0042E05C 0A 00 00 00... // n
0042E060 00 00 00 00... after this statement is executed, the memory space on the n has also changed, except for the initial value of n.
We then press F5 to directly execute the breakpoint, and then execute it in a single step. We found that this time only the value of n has changed, so we guess the bit above may be a static flag bit, if the value is 0, it indicates that initialization is not performed. If the value is 1, it indicates that initialization has been performed and will not be performed the next time we come in. To verify our guesses, now we can add a few languages to the function to modify the value. Reference:
Void fun (int I)
{
Static int n = I;
Int * p = & n;
Cout <n <endl;
++ N;
//
// Wait until we write code here to make static int n
// This function is initialized every time.
-- P;
* P = 0;
//
} After writing the above two sentences, let's execute it. Does it find that the execution result is different from the above? Every time you enter the function, the initial value is assigned to the static int n.

Next we will look at two static types. In the above Code, we will add a static variable; reference:
Void fun (int I)
{
Static int n1 = I;
Static int n2 = I;
Int * p = & n1;
Cout <n1 <endl;
++ N1;
//
// Wait until we write code here to make static int n
// This function is initialized every time.
-- P;
* P = 0;
//
} Continue to play.
Two static variables are referenced in the memory before initialization:
0042E050 00 00 00 ....
0042E054 00 00 00 ....
0042E058 00 00 00 ....
0042E05C 00 00 00 00... // n1
0042E060 00 00 00.../n2
0042E064 00 00 00 00... after the static int n1 = I; statement is executed, the memory value becomes like this reference:
0042E058 01 00 00 00 ....
0042E05C 0A 00 00 00 ....
0042E060 00 00 00... then we will execute it in a single step.
The memory value becomes like this. Reference:
0042E058 03 00 00 00 ....
0042E05C 0A 00 00 00 ....
0042E060 0A 00 00 00... this makes it obvious that the compiler uses one bit to indicate whether a static variable has started.

The above is the initialization of static with variables. What is the situation of constant initialization?
We changed the above Code to reference:
# Include <iostream. h>
Void fun (int I)
{
Static int n1 = 0x12345678;
Int * p = & n1;
Cout <* p <endl;
}
Int main (void)
{
For (int I (10); I> 0; -- I)
{
Fun (I );
}
Return 0;
} When the pointer gets the value, we end debugging. The address here is 0x0042ad64.
Now, let's end the play. Use winhex to open the generated executable file and press Alt + g to jump to the n address. here we need to subtract 0x400000, that is, 2ad64. See our initial values.
Because intel uses the small-end method, the value we see is the opposite.


Next, let's explore the const principle;
Let's take a look at the reference of a program section:
# Include <iostream. h>
Int main (void)
{
Const int n = 1;
Int * p = (int *) & n;
* P = 0;
Cout <n <endl;
Cout <* p <endl;
Return 0;
} Let's execute it. Is the result different from what we expected? We have a breakpoint at the first line and a line of execution.
Verify that each step is correct.
When * p = 0 is executed, we find that the value of n MEMORY has changed to 0, but why is the execution result disappointing?
Press Alt + 8 to open the Assembly window. Reference:
7: cout <n <endl;
00400001e push offset @ ILT + 40 (endl) (0040102d)
00411623 push 1
00411625 mov ecx, offset cout (0042e070)
00400002a call ostream: operator <(004012a0)
0041162F mov ecx, eax
00411631 call @ ILT + 30 (ostream: operator <) (00401023)
8: cout <* p <endl;
00411636 push offset @ ILT + 40 (endl) (0040102d)
0041273b mov edx, dword ptr [ebp-8]
0041163E mov eax, dword ptr [edx]
00411640 push eax
00411641 mov ecx, offset cout (0042e070)
00411646 call ostream: operator <(004012a0)
0041164B mov ecx, eax
0041164D call @ ILT + 30 (ostream: operator <) (00401023) the original compiler replaced our const variable with a constant!
Some may think, why do we need to allocate space for the const variable? This is for everyone to think about, or if you want to design the compiler for you, you will also implement it like this!


End

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.