In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
This article is to share with you about the steps to run the program. The editor thinks it is very practical, so share it with you as a reference and follow the editor to have a look.
To convert a source program written in a high-level language into an executable program, it is necessary to "compile and connect". Source programs written in high-level languages cannot be executed directly on the machine and must be compiled and linked.
To run the program, it must go through four steps: preprocessing, compilation, assembly and linking. Next, we will explain these processes in detail through a few simple examples.
Some of the options used above need to be explained.
If you use the gcc command without any options, the whole process of preprocessing, compiling, assembling and linking will be performed by default. If there is nothing wrong with the program, you will get an executable file. The default is a.out.
-E option: prompt the compiler to stop after preprocessing, and then the compilation, assembly, and linking will not be executed.
-S option: prompts the compiler to stop after compilation instead of assembling and linking.
-c option: prompts the compiler to stop after executing the assembly.
Therefore, these three options are equivalent to limiting the stop time for the compiler to perform the operation, rather than singling out a step for execution.
The implementation process of the above procedures should be very familiar to everyone, so there is no need to waste breath.
First, pre-processing:
Using the-E option means that only the precompilation is performed and a .i file is generated accordingly.
Actions performed by the preprocessing process:
Delete all "# define" and expand all macro definitions
Handle all conditional compilation instructions, such as "# if", "# ifdef", "# elif", "# else", "# endif"
Process the "# include" precompiled instruction and insert the included header file into the location of the compilation instruction. (this process is recursive because the included files may also contain other files.)
Delete all comments "/ /" and "/ * /".
Add line number and file name identification to facilitate the later compiler to generate debugging line number meaning and compile time to generate compilation errors or warnings to display line numbers.
Keep all # pragma compilation instructions because the compiler needs to use them.
Use a simple program to verify that the facts are as described above.
Write a simple program, then use the-E option to perform the preprocessing process, open the generated .i file and compare it with the source file, and the result is clear at a glance
As for adding line numbers to code, this is not demonstrated here. We do not add line numbers manually when we write code. The line numbers we see are automatically added by our own editing tools, and these line number compilation systems are not visible. However, we find that if there is a problem with which line of code, we will give a hint that what is wrong with which line of code. This has proved that the compiler automatically adds line numbers.
II. Compilation:
Use the-S option to indicate that the compilation operation ends after execution. Generate a .s file accordingly.
The compilation process is the core part of the whole program construction. if the compilation is successful, the source code will be converted from text to machine language. the compilation process is to carry out a series of lexical analysis, syntax analysis, semantic analysis and optimization to generate the corresponding assembly code files.
Lexical analysis:
Lexical analysis uses a program called lex to implement lexical scanning, which splits the input string into tokens according to the lexical rules previously described by the user. The resulting tokens are generally divided into keywords, identifiers, literals (including numbers, strings, etc.) and special symbols (operators, equal signs, etc.), and then they are placed in the corresponding table.
Syntax analysis: the parser parses the token sequences generated by lexical analysis according to the grammar rules given by the user, and then constructs them into a syntax tree. For different languages, only the grammatical rules are different. There is also a ready-made tool for parsing called yacc.
Semantic analysis:
The parsing completes the syntax analysis of the expression, but it does not know whether the statement is really meaningful or not. Some sentences are grammatically legal, but have no practical meaning, such as multiplication of two pointers, which requires semantic analysis, but the only semantics that the compiler can analyze is static semantics.
Static semantics: semantics that can be determined at compile time. It usually includes declaring a match to a type and a type conversion. For example, when a floating-point expression is assigned to an integer expression, it implies a conversion from floating-point to integer, and semantic analysis needs to complete this conversion, for example, assigning a floating-point expression to a pointer, this is definitely not possible, semantic analysis will find that the two types do not match, the compiler will report an error.
Dynamic semantics: semantics that can only be determined at run time. For example, if two integers are divided, there is no problem in syntax, and the types match, which sounds fine, but if the divisor is 0, there is a problem, and this problem is not known in advance. Only at run time can you find that he has a problem, which is dynamic semantics.
Intermediate code generation
Our code can be optimized, for some values that can be determined during compilation, it will be optimized. For example, in the above example, 2: 6, its value can be determined to be 8 during compilation, but it is difficult to optimize the syntax directly. At this time, the optimizer will first convert the syntax tree into intermediate code. Intermediate code is generally independent of the target machine and the running environment. Does not include the size of the data, the address of the variable, the name of the register, etc. Intermediate code has different forms in different compilers, and the more common ones are three-address code and P-code.
Intermediate code allows the compiler to be divided into front-end and back-end. The front end of the compiler is responsible for generating the intermediate code independent of the machine, and the back end of the compiler changes the intermediate code into machine code.
Target code generation and optimization
The code generator converts intermediate code into machine code, a process that depends on the target machine, because different machines have different word lengths, registers, data types, and so on.
Finally, the object code optimizer optimizes the target code, such as choosing the appropriate addressing mode, using unique instead of multiplication and division, deleting redundant instructions and so on.
III. Compilation
The assembly process calls the assembler as, which is used to convert the assembly code into instructions that can be executed by the machine. Almost every assembly statement corresponds to a machine instruction.
Use the command as hello.s-o hello.o or use gcc-c hello.s-o hello.o to execute until the end of the assembly process, and the corresponding file is the .o file.
IV. Links
The main content of the link is to correctly link up the parts referenced by each module. Its job is to correct the references of some instructions to other symbolic addresses. The linking process mainly includes address and space allocation, symbol resolution and redirection.
Symbolic resolution: sometimes called symbolic binding, name binding, name resolution, or address binding, actually refers to the use of symbols to identify an address.
For example, int a = 6; such a code, using a to identify a block of 4 bytes of space, the contents of the space is 4. 5%.
Relocation: the process of recalculating the addresses of each destination is called relocation.
The most basic link is called static link, which compiles the source code file of each module into an object file (Linux:.o Windows:.obj), and then links the target file with the library to form the final executable file. A library is actually a set of packages of object files, where some of the most commonly used code is mutated into object files and packaged and stored. The most common library is the runtime library, which is a collection of basic functions that support the running of a program.
Thank you for reading! This is the end of this article on "what are the steps to run the program?". I hope the above content can be of some help to you, so that you can learn more knowledge. If you think the article is good, you can share it for more people to see!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.