Keil Optimization Level setting
Optimization level description (for reference only):
The Code optimization bar is used to set the C51 level of optimization. There are 9 levels of optimization (as written in the book), and the high level of optimization includes all the previous levels of optimization. The various levels are described below:
0-Level optimization:
1, constant folding: Whenever possible, the compiler executes a calculation that evaluates to a constant number, including the calculation of the run address.
2. Simple Access optimization: The internal data and bit address of the 8051 system are optimized for access.
3, jump optimization: The compiler will always postpone the jump to the final target, so jump to jump between the command is deleted.
1-Level optimization:
1, dead code elimination: Useless code snippet is eliminated.
2, jump veto: According to a test backtracking, conditional jumps are carefully checked to determine whether it can be simplified or deleted.
2-Level optimization:
1, data coverage: Suitable for static coverage of data and bits are identified and marked out. Connection Locator BL51 By analyzing the global data stream, select the segment that can be statically overwritten.
3-Level optimization:
1, "Peep hole" optimization: The redundant mov command is removed, including unnecessary loading of objects from memory and loading constant operation. In addition, if you can save storage space or program execution time, complex operations will be replaced by simple operations.
4-Level optimization:
1, register variables: to make the automatic variables and function parameters in the work register as far as possible, the data memory space will not be reserved for these variables.
2. Extended access optimizations: Variables from the idata, XDATA, pdata, and code regions are included directly in the operation, so it is not necessary to load them into intermediate registers most of the time.
3, local common sub-elimination: If there is a recurring calculation in the expression, the results of the first calculation are saved, and whenever possible, will be used as a subsequent calculation, so you can eliminate complex calculations from the code.
4, Case/switch statement optimization: The Case/switch statement as a jump table or jump string optimization.
5-Level optimization:
1, global common sub-elimination: Whenever possible, the same sub-expression inside the function is evaluated only once. The intermediate result is stored in a register in place of the new calculation.
2, Simple cycle optimization: the constant occupies a period of memory in the cycle of re-operation is optimized.
6-Level optimization:
1, Loop Loop: If the program code can be executed faster and more efficiently, the program loop will be cycled.
7-Level optimization:
1. Extended ingress Optimization: Using DPTR data pointers for register variables when appropriate, pointers and array accesses are optimized to reduce program code and improve execution speed.
8-Level optimization:
1, public tail Merge: when there are multiple calls to the same function, some setup code can be reused, thus reducing the length of the program code.
9-Level optimization:
1. Common subroutine Block: detects the repeated sequence of instructions and converts them to subroutines. C51 even re-arranges the code to get more sequences of repeated use instructions.
Of course, the optimization level is not as high as possible, and should be appropriately selected according to the specific requirements.
In-depth analysis of Keil C51 bus peripheral operation problem
Read the "SCM and Embedded System Application" in the 10th issue of 2005 Magazine, "Experience Exchange" column of an article "Keil C51 on the same port continuous reading method" (original), the author believes that this paper does not carry out in-depth and accurate analysis of the two solutions mentioned in the article is not straightforward and simple. I think this is not Keil C51 can not deal with a port for continuous reading and writing, but the use of Kei1 C51 is not familiar with the design of the problem is not detailed enough, so write this article.
In this paper, the problems mentioned in the original text, three different from the original solution. Each method is more straightforward and straightforward than the one mentioned in the original, and the design is more prescriptive. (no criticism, please forgive the original author)
1 Problem Review and analysis
As mentioned in the original text: in the actual work encountered on the same port repeated continuous reading, Keil C51 compilation did not achieve the expected results. The author of the original C compiled assembler analysis found that the same port of the second read statement is not compiled. But unfortunately the original author did not analyze the reasons for not being compiled, but rushed to use some less standardized methods to test out two solutions.
For this issue, it is easy to see the manual of Keil C51: The KeilC51 compiler has an optimization setting, and different optimization settings will produce different compilation results. In general, the default compilation optimization settings are set to 8-level optimizations, and the actual maximum can be set to 9-level optimizations:
1. Dead code elimination.
2.Data overlaying.
3.Peephole optimization.
4.Register variables.
5.Common subexpression Elimination.
6.Loop rotation.
7.Extended Index Access Optimizing.
8.Reuse Common Entry Code.
9.Common Block subroutines.
And the above problem is precisely due to the Keil C51 compilation optimization produced. Because the peripheral address is defined directly in the source program as follows:
unsigned char xdata MAX197 _at_ 0x8000
Use _at_ to define the variable MAX197 to the external extended RAM specified address 0x8000. Therefore, the Keil C51 optimization compilation is, of course, considered repeated reading the second time is useless, directly with the first read the result is possible, so the compiler skipped the second read statement. At this point, the problem is at a glance.
2 workaround
It is easy to make a good solution from the above analysis.
2. 1 The simplest and most straightforward way
The program does not have to be modified at all, and the Keil C51 's compilation optimization selection is set to 0 (not optimized). Select Target for the Project window, then open the Options for Target Settings dialog box, select the C51 tab, and select "level" in Code optimiztaion as "0:costant folding". After compiling again, you will find that the result of the compilation is:
CLR Maxhben
MOV DPTR, #MAX197
MOVX A, @DPTR
MOV R7,a
MOV DOWN8,R7
Setb Maxhben
MOV DPTR, #MAX197
MOVX A, @DPTR
MOV R7,a
MOV UP4,R7
Two read operations are compiled.
2. 2 The best way
Tell Keil C51, this address is not the general expansion RAM, but the connected device, with the "volatile" feature, each read is meaningful. You can modify the variable definition to increase the "volatile" keyword to describe its characteristics:
unsigned char volatile xdata MAX197 _at_ 0x8000;
You can also include the system header file in the program, "#include <absacc.h>", and then modify the variable in the program, defined as the direct address:
#define MAX197 Xbyte
This way, the settings of the Keil C51 can still retain advanced optimizations, and the same two reads are not skipped by the compilation results.
2 3 Hardware Solutions
The MAX197 data is connected directly to the bus, and the address bus is not used, and a port line is chosen to operate the high and low bytes. A simple way to modify this is to use a single address line to select a high or low byte. For example: Will P2. 0 (A8) connected to the original P1. 0 Connected Hben feet (5 feet of MAX197). Define the operating address of the high and low byte in the program:
unsigned char volatile xdata max197_l _at_ 0x8000;
unsigned char volatile xdata max197_h _at_ 0x8100;
Put the original program:
Maxhben = 0;
down8=max197;//Read Low 8-bit
Maxhben = 1;
up4=max197;//read High 4-bit
The following two sentences can be changed
down8= max197_l;//Read Low 8-bit
up4=max197_h;//read High 4-bit
3 Summary
Keil C51 has overcome most of the problems and its compilation efficiency is very high after long-term testing and improvement, and the actual use of a large number of developers. For general use. It's hard to find any more problems. The author has roughly studied the results of Keil C51 optimization compilation. Very admire Keil C51 designers of the wisdom, some C program compiled generated by the assembly code. Even the code written directly by the programmer in the assembly is better and more concise by studying the assembly code produced by Kell C51 compilation. It is helpful to improve the level of programming in assembly language.
As you can see from the questions in this article: when you encounter problems in your design. Must not be deceived by the surface phenomenon, do not rush to solve, should be carefully analyzed to find out the cause of the problem. This will solve the problem fundamentally and completely.
Schedule: Keil C51 optimization level and optimization action level description
0 constant merging: The compiler computes the result in advance and, whenever possible, replaces the expression with a constant. Includes run address calculation.
Optimized simple access: The compiler optimizes access to the internal data and bit addresses of the 8051 system.
Jump optimization: The compiler always expands to jump to the final target, and the multilevel jump instruction is deleted.
1 dead Code Delete: The unused code snippet is deleted.
Deny jump: Strict check condition jumps to determine whether the test logic can be reversed to improve or remove.
2 Data coverage: Data and bit segments that are suitable for static overrides are identified and internally identified. The BL51 connection/locator allows you to select segments that can be overwritten through global data flow analysis.
3 Peep Hole Optimization: Remove excess mov instructions. This includes unnecessary loading from the store and constant load operations. Use simple actions instead of complex operations when storage space or execution time can be saved.
4 Register variables: If possible, automatic variables and function parameters are assigned to registers. Stores that are reserved for these variables are omitted.
Optimized extended access: Variables for IDATA, XDATA, pdata, and code are included directly in the operation. It is not necessary to use intermediate registers for most of the time.
Local common subexpression Delete: If you repeat the same calculation with an expression, save the first calculation, and you may use the result later. The extra calculation is deleted.
Case/switch Optimizations: Code that includes switch and case is optimized for jump tables or jump queues.
5 Global Common subexpression Delete: the same subexpression within a function may be evaluated only once. The intermediate results are stored in registers and are used in a new calculation.
Simple loop Optimization: The loop program that fills the storage area with a constant is modified and optimized.
6 Cycle Optimization: The program optimizes the loop if the resulting program code is faster and more efficient.
7 Extended Index Access optimization: Use DPTR for register variables when appropriate. Performs speed and code size optimizations on pointers and array accesses.
8 Public tail Merge: When a function has multiple calls, some of the setup code can be reused, thus reducing the size of the program.
9 Common Block subroutine: detects the loop sequence of instructions and converts them into subroutines. Cx51 even rearrange the code to get a larger loop sequence.
Optimization theory
When it comes to optimization, in fact many people are in distress, because in a C51 software engineer's career, always be Keil optimization play so once to several times. I have been played, must look at the article you have been played, if you say no, it can only say that you write C51 program not much!
Check out KEILC's optimization level options:
0-9 a total of 10 levels of optimization, 0 is the lowest, 9 the highest, a common program, set the highest level and the lowest level, compiled code will sometimes be a long time difference, the DX board demo program For example, 0-level optimization is 14K after the code,9-level optimization is 10K code, before and after the difference of 4 K. It can be seen how big the difference is.
In fact, we don't need to know how the respective levels of Keil will optimize your program or optimize what, we just need to write and treat your program in a rigorous manner. In my personal view, the program can still keep the perfect operation after the 9-level optimization, you know Keil temper.
OK, just say something nice:
Some people are accustomed to the whole program to choose the same optimization level, in fact, each C file can have independent optimization level:
In the workspace, right-select your module (. C) then select options for File XXX and the following interface will appear:
In the C51 option, you can choose to optimize levels and warning levels, and the files that have been independently set will have special tags:
To remind you that the compilation process for this file is not the default setting!
If you think that the module optimization is not fine enough, you can consider the local optimization, that is, a function to implement a certain level of optimization. Local optimizations can be quite useful when you find that a function always becomes unhealthy when you discover Level 9 optimization, but you want other functions and program segments to maintain the highest degree of brevity. This feature is described in the Keil manual:
#pragma OPTIMIZE (x) x is the level of optimization you want, and the general application is as follows:
#pragma OPTIMIZE (6)
void Funa ()
{
}
......
......
#pragma OPTIMIZE (9)
void Funb ()
{
}
The above means that all functions prior to void Funa () to void Funb (), including Funa, are optimized with level 6, and from Funb onwards until later, as long as there is no #pragma OPTIMIZE, the 9-level optimization is used.
Optimize can also have one more parameter, which is speed and size,
Usage: #pragma OPTIMIZE (9,speed) or #pragma OPTIMIZE (5,size)
corresponding to the 9-level optimization, speed-based, or 5-level optimization, the smallest space-based.
4.startup.a51
In the first section of the establishment of the project once mentioned Startup.a51 this thing, that is, when the project was first built a dialog box is used to choose whether to add this A51 file for the project.
In fact, this file to everyone the most profound feeling is: the boot empty RAM. In fact, it has other special uses, such as initializing the stack (many people don't know how much the stack is set at the beginning of the KEILC, and can actually find the answer from this file by software emulation), then the virtual stack of the re-entry function, and the more advanced, the bank's initialization.
Older versions of Keil automatically add the same startup file for each project by default, and later Keil have the option to add a separate startup for each project if you choose to add it. Users can implement some necessary power-up initialization by manually overwriting Startup.a51. For example, the most common: cancel the single-chip microcomputer power-on clear RAM Function!!
On the introduction of startup, I suggest you look at the following article, its explanation is very detailed.
##################################
When it is actually used, it is found that there is a white writing program in the simulation. Breakpoints cannot be set
The search answer is that the optimization level is too high and some common programs are optimized.
Have to lower the optimizer level.
Keil Optimization Level setting