2.1.3 My father and mother: compilers and linker
On the surface, I was created by Visual Studio, and in fact, the real responsibility for compiling the source code to create the executable program HelloWorld.exe is the integrated C + + compiler Cl.exe and linker link.exe in Visual Studio. They chou, is my biological parents.
To facilitate people's writing, reading and maintenance, our source files are written in high-level programming languages that people can understand in C + +. However, computers do not understand this high-level language, and they cannot directly execute source files written in high-level languages. Therefore, a translation work is needed here, translating the high-level C + + language that people in the source file can understand into machine languages that machines can understand. My dad's compiler is actually a translator, and his job is to translate a source file (. cpp) written in a high-level language of C + + into a target file (. obj) expressed in a machine language that can be read by a computer, which is commonly referred to as compilation.
In Visual Studio, my father's name is Cl.exe, you can find the "VS2012 developer Command Prompt" in the Start menu, and then in the Open DOS window through the CL command to ask his old man, a CPP source file compiled into the corresponding obj target file. For example, to have my dad compile my source file HelloWorld.cpp into the corresponding target file helloworld.obj, you can use the following command:
CL/C/EHSC HelloWorld.cpp
Where CL is the directive that invokes the compiler, and subsequent options are used to specify the compiler's compilation behavior. The "/C" here means that only the compiler does not link; "/EHSC" specifies what exception handling model the compiler uses; the last option, HelloWorld.cpp, is the C + + source file that will be compiled. Source file HelloWorld.cpp After compiling my dad's compiler, I get only a target file that can't be executed directly helloworld.obj, and I need my mom. The linker will use this target file and the standard library target file provided by Visual C + + (for example, LIBCPMT.LIB) is integrated into the final executable file (from the standard library target file to find the external functions used in the program target file, and then fill in the program target file to generate the final executable file), this process is called a link. In the "VS2012 developer Command Prompt", you can use the following command to please my mother linker link.exe to complete this link process:
Link Helloworld.obj
Of course, the whole work of compiling links can also be done by my dad compiler cl.exe a person:
CL/EHSC HelloWorld.cpp
After my dad and my mom compiled the link process, I changed from a source file (HelloWorld.cpp) to an executable (HelloWorld.exe), and I just went to the next. The entire process, shown in 2-6:
Figure 2-6 Compiling the link process
2.1.4 C + + program execution process
Once the executable is generated, the operating system can be given instructions to start the execution of the file. The execution of a program begins with its main function. But before we get into the main function, the operating system will do a lot of prep work for us. For example, when the operating system is instructed to execute a program, it first creates the appropriate process and allocates the private process space, and the loader maps the data segments and snippets of the executable to the virtual memory space of the process, and the operating system then initializes the global variables defined in the program. To do these preparations, the program can go into the main function and start executing.
After entering the main function, the program will follow the source code for me to make a life plan, a statement of a statement down execution, step by step down. You must remember, my source code is this:
int Main () { // output "Hello world!" on the screen "String cout<<"Hello world! "<<Endl; return 0 ;}
As you can see from here, after entering the main function, my first statement is:
cout<<"Hello world! "<<endl;
The meaning of this statement is to let me Show "Hello world!" in the DOS window. Such a string of text, so I began to control the DOS window, in which to display this string of text, complete the programmer through this line of code to my task.
The Next statement is:
return 0;
This short statement declares the end of my life. It represents the end of the main function, and the entire program executes. Figure 2-7 shows my short and glorious life!
Figure 2-7 Hello World program short and glorious Life
Learn more: The story behind C + + program execution
In the example above, we see that the execution of a C + + program is executed from the main () function, starting with the first statement. The process looks very simple, but there are more stories behind each statement.
In the Disassembly view in Visual Studio Debug mode (opened in debug mode via the Alt+8 shortcut key), we can see the assembly code corresponding to each statement in the C + + program. This, the program of the statements do what things, how each function is implemented, are at a glance. The HelloWorld program simply outputs a string, but when we unpack the program, we can see that it does a lot of things behind it. The HelloWorld program in the Assembly view is as follows (the assembly code is too long and we keep only the key operations):
#include <iostream>using namespacestd;intMain () {//complete the preparation work00dc4ec0 push ebp 00DC4EC1 mov ebp,esp 00dc4ec3 sub esp,0c0h//... ..00DC4EDC Rep stos dword ptr Es:[edi]//Complete the Task//on the screen output "Hello world! The stringcout<<"Hello world!"<<Endl;00dc4ede mov esi,esp 00dc4ee0 mov eax,dword ptr ds:[00dd031ch] 00dc4ee5 push eax 00dc4e E6 push 0dccc70h 00dc4eeb mov ecx,dword ptr ds:[0dd0318h] 00dc4ef1 push ecx//invoke the operator in the standard library to complete the task00DC4EF2 Call std::operator<<<std::char_traits<Char> >(0DC12A3H) 00DC4EF7 add ESP,800DC4EFA mov ecx,eax 00DC4EFC call dword ptr ds:[0dd0324h] 00DC4F02 cmp esi,esp 00dc4f04 C All __rtc_checkesp (0dc132ah)return 0; 00dc4f09 xor Eax,eax}
When we start a program, the operating system creates a new process to execute the program. The so-called process is an instance of the application. When the operating system creates a process, it allocates a certain amount of memory space (the default heap) as its private virtual address space. Typically, an application's execution corresponds to a process that manages everything that the program is running, such as resource allocation and scheduling, and so on. However, as the dispatcher of the program execution, it is not responsible for the execution of the program, the specific execution of the work, it is created by the thread to complete. Each process has a main thread, and if it is a multithreaded application, it can have multiple worker threads. A thread does not own a resource (it uses the resources of the process it belongs to), but it has its own execution entry, sequential series of execution, and an execution endpoint.
Here, when the main thread responsible for executing the program is created, it enters the main () function to begin execution. It first performs some initialization work, such as saving the field environment, initializing the heap, and passing the program parameters, and so on, then executing the specific program code. Although the C + + program code has only one line, in the Assembly view, it is decomposed into multiple steps to complete. The execution of the main function is only for the operation of some registers and the call to the library function. For example, the first sentence of the main () function is to save the current address with "Push EBP" (in assembler Code, EBP represents the current address). Here we must be wondering why the first thing after entering the main () function is not to see the output of a string in C + + program code, but to save the current address? In fact, what we see in the program code is just a description of what we are going to do, and what we really want to do with the C + + program is to do a lot of things for us behind the scenes. The "Push EBP" here saves the current address in order for the main () function to return to its original address and continue to execute after the execution is complete. In addition to the Register operation (assembly instructions such as push, MOV, and pop), it is more important in the assembly code to call the other functions through the "invoke" instruction. For example, call __RTC_CHECKESP (0DC132AH) is called to invoke the __rtc_checkesp () function (which is added by the compiler in debug builds) to check if the stack is balanced after the program has finished executing.
In the Assembly view, we can see that every C + + statement has a story behind it. You can really understand this statement only if you understand the story behind each statement. This also tells us that if we find that the behavior of a statement is abnormal and we cannot find the reason from the code level, we need to look for the real reason behind this statement.
Two major tasks of the 2.1.5 program: describing data and processing data
The purpose of writing programs is to use programs to solve problems in the real world. It is observed that all of these problems are solved by taking data as input, then processing the data, and finally obtaining the result data. So, since I was used to help people solve the problem, then my task is naturally inseparable from the description of the data and the processing of the data. As shown in 2-8.
People gave me a definition of the formula:
Data + algorithm = Program
The data can be seen as an abstraction and description of everything in the real world. For example, in a C + + program, we abstract data from the real world into various data types, such as the fact that we abstract integers into int classes, and we abstract decimals into double types. Then, in turn, the variables defined by these types are used to describe a specific data that we encounter in life. For example, a variable nwidth defined by the int type is used to describe the width of a rectangle, a variable strname defined by a string type is used to describe a person's name; we can even create custom data types to describe more complex things, For example, we can create a human data type to abstract "human" complex things, and then use it to define a variable to describe a specific person. In a word, it is my first task to use data to abstract and describe things in the real world.
Figure 2-8 The purpose of my life
Describing the real world with data is not my ultimate goal, my ultimate goal is to process the data to get the desired result data. For example, we describe the width and height of a rectangle with nwidth and nheight, however, this is not the result data we want, we want the area of the rectangle. Therefore, we must also deal with the two data nwidth and nheight, the "*" symbol to calculate the product of two numbers in order to obtain the rectangular area we want. The abstraction of the process of data processing is called an algorithm. My second task, then, is to describe and express the algorithm and process the data to get the final result.
Know more: Data structure + algorithm = Program
The equation "Data + algorithm = Program" is distorted by the well-known "data structure + algorithm = program". It was first proposed by Mr. Pascal's father, the pioneer of structured programming, Niklaus Wirth, which abstracted the core content of a program as a data structure for expressing data and an algorithm for processing data. The "Data + algorithm = Program" We put forward here is a concrete description of a program that is composed of the data it wants to process and the algorithm that handles the data in detail. Both of the equations are correct, just to describe the different angles of the program.
Data and algorithms accompany my life. In the small HelloWorld.exe, there is also the existence of data and algorithms. For example, to the screen output "Hello world! "Statement:
cout<< "Hello world!" <<endl;
Among them, "Hello world! "is a string of data to be output to the screen. The entire statement represents the processing of the string data: The string is displayed on the screen. Data and algorithms are always so inseparable, and become my life to complete the two major tasks.
Hello, C + + (4) 2.1.3 My father and mother: compiler and linker 2.1.4 the story behind C + + program execution