Opening
Almost every typeProgramIn the syntax of the design language, there will be a loop of statements, jump. Like the most well-known C language, there are for, while, do --- while and so on. These loops are generally easy to understand and use, and are also helpful for implementing the logic in the program.
But many people do not know how these loops, jumps inside the computer, and is implemented at the underlying layer. Therefore, there is still no good solution in the case of problems, or even if the program is written, the internal logic is still separated by a fog.
For example, someone has the following question:
For (I = 0; I <10; I ++)
{
Printf ("% I", I );
}
When will I ++ IN THE for statement be executed? When the loop starts, do I ++ or printf ("% I", I) in parentheses be executed first )? That is to say, is the first printed number 0 or 1?
I believe that many people have encountered this problem, that is, when the for loop ends, the I value is not very definite. it is not worthwhile to make it difficult. If you have such questionsArticleIt is worth looking.
This article will open up the fog and let you see the essence of the loop.
This article mainly talks about these loops in C and the internal implementation mechanism of Jump statements. By in-depth understanding of their inner, you will be given a clearer logic during programming and easier troubleshooting when problems arise.
Note: This article involves some basic assembly knowledge. We will analyze the Assembly representation of for, while, do --- while and so on to find out their implementation mechanism.
If -- else
If -- else is a basic conditional transfer control command, which can also be said to be the basis for the implementation of loop jump.
Let's take a look at a specific example. The function absdiff () compares the values of X and Y and returns the absolute values of their differences.
We have created a C language version (a), a goto version (B), and a corresponding Assembly Form (c ):
The Goto version is created to better understand its Assembly form. Because the GOTO statement in it is similar to the jump statement in assembly.
C In ()CodeYou don't have to explain it more. Everyone should be able to understand it.
(B) in the form of a got0 statement: Row 4th is a jump statement that redirects to the execution of row 8th. That is to say, when the 3rd rows meet the conditions, the system jumps to the 8th rows for execution. If the condition of row 3rd does not meet, the statement of row 5th is executed. Then jump to the end of the Code unconditionally: "Goto done;" using a GOTO statement is generally considered a bad programming style, because such statements are usually difficult to debug and read, here, the GOTO statement is used to construct a C statement similar to Assembly implementation.
(C) This is the focus of our discussion. In fact, the Assembly Form of the conditional jump instruction is similar to the Goto form.When a statement is redirected, the process is as follows: first, determine whether a certain condition is met. If yes, the system jumps to a specified code segment to continue executing the program. If not, the system executes another statement.
To figure out how it is implemented internally, let's take a closer look at its assembly instruction form (c)
Rows 1 and 2 of the program get the value of x y. Put it in the edX eax register, and compare the size of x y in the third line (that is, compare the size of edX EAK). If x> Y, it jumps. execute x-y in L2 (lines 8 and 9), put the result in the return value, and then execute the program to the end of the program in sequence. l3. Otherwise, if the row 3 determines that the result is x <Y, the statement will not jump, execute y-x sequentially, and jump to the end of the program. l3.
Now, we have a basic understanding of the execution mechanism of IF -- else. It mainly determines the condition value first. In this example, there are 3rd statements: CMPL % eax, % EDX. Those who have learned the Assembly should know that CMPL is a comparison command, and its execution will affect the flag. Make a simple assumption: cmpl a and B compare the sizes of numbers A and B. The comparison results are stored in the flag f. When A> B, F is 0, A <BF is 1. The following jge. L is a jump statement. Its execution is related to the result of the previous price comparison, which is also reflected in the flag f. When F is 1 (a <B), B-A is redirected to. l2. When the comparison result is A> B and the flag is 0, the jge does not jump and the program continues to run.
The general template of IF -- else in C is as follows:
Here, test-expr is an integer expression. If its value is true (1,> 0), the first branch statement is executed. Otherwise, the second branch statement is executed. But in any case, only one of them will be executed.
For this template, the implementation of assembly is usually described in the following form: (the C language is used here)
The assembler generates their own code for then-Statement and else-statement, and executes the corresponding code through conditional jump.
Note: The program is not intelligent. When performing a jump, there are only two types of judgments (true and false), and the internal jump form is based on the go to mode. Therefore, although goto is rarely used in programming, it is very important to understand the program jump. I think the Goto implementation method is similar to the final implementation method of the program.
Do --- while
C provides the multi-medium loop structure, do-while and for, but there is no corresponding instruction in the Assembly. Through the analysis of IF-Else, we have learned the basic implementation method (goto) of conditional jump in C in assembly. The loops to be discussed now, there is a condition judgment link in the loop. When the condition is met, the loop body continues. If the condition is not met, the loop body jumps out. Unlike if-Else, the conditional expression may change, that is, the condition of each judgment is different from that of the previous judgment.
As long as you understand the above content of IF-Else, other loops can be implemented through improvements to if-Else.The Goto form of these loops is given first, so that the internal implementation method can be quickly deduced.
General Form:
The general form of do-while is as follows:
Do
Body-staement
While (test-expr)
The effect of this loop is to repeatedly execute body-staement and evaluate test-expr. If the result is not 0, continue to execute. We can see that the body-statement will be executed at least once.
The general form of do-while can be translated into the following GOTO statement:
Loop:
Body-Statement
T = test-expr;
If (t)
Goto loop;
For the above goto form, you can first think about how the Assembly will be implemented: Put the code in the loop in a separate code segment (including the if judgment jump part) and execute the program in sequence, you do not need to determine the conditions for the first execution. Run the "body-statement" command to determine the condition. If the condition is met, continue the loop.
Now, let's look at a specific example:
This is a function implementation for calculating factorial,
(A) Is C code,
(C) Is the corresponding Assembly Form
(B) The ing between registers and variables in the Assembly.
(A) the code in is relatively simple and will not be explained. Now look at the code in (c:
Row 1st is the value of function parameter n, which is placed in the register EDX. row 2nd sets result = 1. Row L2 to indicate that this is a loop body. Rows 5 and 5 in (c) implement the functions of rows 5 and 6 in (.
(C) the condition for judging the cycle in row 6th. If the condition is met, the system executes the jump statement in row 7th.
As described in the general form of do-while, the body-staement will be executed at least once, which is also reflected in the assembly code. Observe the loop body L2, there is no L2 jump code in L2, that is, when the program is executed in sequence, L2 will be executed at least once, and then judge whether to continue executing the loop body L2 in L2.
While
The whil loop is similar to do-while. Its general form is as follows:
While (test-expr)
Body-Statement
Unlike do-while, it first evaluates test-expr, so the body-statement may not be executed once. There are multiple ways to translate while into machine code. One of the common ways is to translate it into the do-while format. Add a judgment condition before the first execution of the loop body. If the condition is met, enter the do-while loop body. If the condition is not met, skip the loop body directly. That is to say, the body-statement may not be executed once.
Next, convert while to do-while loop:
If (! Test-expr)
Goto done;
Do
Body-Statement
While (test-expr );
Done;
Next, we can convert the do-while loop to the GOTO statement:
T = test-expr;
If (! T)
Goto done;
Loop:
Body-Statement
T = test-expr;
If (t)
Goto loop;
Done
This goto version and do-while version only add a judgment condition before the loop body loop. If the condition is met, execute the do-while loop body in the above section, if not, skip the loop.
Through the above goto version, you can now think about how the while assembly is implemented:
Now we can guess that the while Assembly only makes some changes based on the do-while Assembly: Add a judgment condition before the loop body loop. If the condition is true, execute the loop, if not, skip the loop.
The following is an example:
Still calculate the factorial of N, but this time it is implemented using the while
The following is the C code:
This is very simple, so I will not explain it. Let's look at his goto form below:
As described above, condition judgment is added to rows 3 and 4. If the condition does not meet the conditions of rows 3 and 4, the loop body is directly attacked, the loop body loop is entered only when the conditions are met. In the loop, 7 and 8 rows perform necessary operations to calculate the factorial, and 9 and 10 rows determine whether to continue the loop by judging test-expr.
Well, let's look at the while Assembly form below:
Now let's take a look at the assembly code with more experience. Here, the 3 and 4 lines of execution conditions determine whether to enter the loop body. l10 is equivalent to lines 4 and 5 in the Goto version. If not, Jump directly. the location of L7.
Let's take a look. l10 cycle body: 6 and 7 are required to perform factorial operations, which is equivalent to 7 and 8 rows in GOTO. Here, 8 and 9 rows determine whether the loop continues, it is equivalent to 9 and 10 rows in Goto.
For Loop
The general form of the For Loop is as follows;
For (init-expr; test-expr; Update-expr)
Body-Statement
When learning C, we will probably mention that the for loop can be expressed with while:
Init-expr
While (test-expr ){
Body-Statement
Update-expr
}
The program first initializes the value of the expression init-expr, and then enters the loop. First, the test-expr value is evaluated for the recycling. If the value is false, the program exits the loop, otherwise, execute the loop body-Statement and update the value of the update-expr expression.
Based on the transformation from Do-while to while, the do-whle format is given first:
Then convert it into the Goto code:
As above, we will use an instance to describe the problem:
Factorial functions written using the For Loop
The factorial calculation function written in the for loop starts from 2, which is different from the previous one, but this does not affect the structure of its logical implementation. In this code, the composition of the For Loop is as follows:
The above analysis shows the Goto format:
So far, the C form and goto form have been provided in the instance. Please refer to his assembly form:
I have explained a lot above. I will not explain this assembly instruction here. I should be able to understand it above.
Start question
Now, you should find out the problems mentioned at the beginning of the article.
For (I = 0; I <10; I ++)
{
Printf ("% I", I );
}
Now you should know when to execute I ++ settings and when to execute printf ("% I", I.
According to our analysis, the execution sequence should be as follows:
1. initialize I = 0
2. Determine whether the condition meets I <10 is true
3. If it is true, execute the cyclic body printf ("% I", I), and execute the auto-increment operation I ++.
You can run this code in your own compiler to check whether the output is 0 or 1 (according to our analysis, we should start from 0)
Summary
In fact, the reason described in this article is very simple, that is, the implementation of loops in C language. If you are operating in Linux, it is easier to understand this part. In Linux, You can intuitively see the compiled Assembly form of a program, analyze your programs on your computer so that you are more interested and more profound in learning.
Brief Introduction:
Linux Compiler: GCC,
Executable File Viewer: objdump. Another one seems to be elfread. you are not sure.
If you debug the preceding for statement, you can use the gdb debugger to execute the program step by step and track the value of the variable. These commands in Linux are not the focus of this article.
The full text is complete.
Http://www.cnblogs.com/yanlingyin/
A fish, yanlingyin @ blog
Yin Yaling
E-mail: yanlingyin@yeah.net