Keil C51 compile/link/optimize
1. C51 compilation library and code optimization technology
As shown in the figure below: You can select the corresponding library file according to the needs of the optimization level.
Configure it through Keil -> Target under Memory Model / code Rom size
SMALL:所有变量都被定义在8051单片机的片内RAM中,对这种变量的访问速度最快。
另外,堆栈也必须位于片内RAM中,而堆栈的长度是很重要的,实际栈长取决与不同函
数的嵌套深度。采用SMALL编译模式与定义变量时指定data存储器类型具有相同效果。
COMPACT:所有变量被定义在分页寻址的片外XRAM中,每一页片外XRAM的长度为256字节:
即所有变量存储在片外XRAM的某一页中。这时对变量的访问是通过寄存器间接寻址
(MOVX @R0,MOVX @R1)进行的,变量的低8位地址由R0和R1确定,变量的高8位地址由P2口确定。
采用这种模式时,必须适当改变配置文件STARTUP.A51中的参数:PDATASTART和PDATALEN;
同时还必须对uVision2的“Options选项/BL51 Locator 标签页/Pdata框”中键入合适的地址参数,
以确保P2口能输出所需要的高8位地址。
采用COMPACT编译模式与定义变量时指定pdata存储器类型具有相同效果。
LARGE:所有变量被定义在片外XRAM中(最大可达64KB),使用数据指针DPTR来间接访问变量
(MOVX @DPTR),这种编译模式对数据访问的效率最低,而且将增加程序的代码长度。
采用LARGE编译模式与定义变量时指定xdata存储器类型具有相同效果。
1.1 Code optimization
C51 can optimize the code written by even experienced programmers. There are 9 optimization levels in total. All optimization methods of C51 are as follows:
Level 0 (Constan folding) optimization includes:
a. Constant folding: Whenever possible, the compiler performs calculations that convert expressions into constant numbers, including calculations of run addresses. b. Simple access optimization: optimize access to the internal data and bit addresses of the 8051 system. c. Jump optimization: The compiler always delays the jump to the final target, so the commands between jumps and jumps are deleted.
Level 1 (Dead code elimination) optimizations include:
a. Dead code elimination: Useless code segments are eliminated. b. Jump veto: Based on a test backtracking, conditional jumps are scrutinized to see if they can be simplified or removed.
Level 2 (Data overlaying) optimizations include:
a. Data coverage: Data and bit fields suitable for static coverage are identified and marked. The connection locator BL51 selects segments that can be statically covered by analyzing the global data flow.
Level 3 (Peephole optimization) optimization includes:
a. "Peehole" optimization: remove redundant MOV commands, including unnecessary operations of loading objects from memory and loading constants. In addition, complex operations will be replaced by simple operations if storage space or program execution time can be saved.
Level 4 (Register variables) optimizations include:
a. Register variables: Make automatic variables and function parameters located in working registers as much as possible. Whenever possible, no data memory space will be reserved for these variables. b. Extended access optimization: Variables from IDATA, XDATA, PDATA and CODE areas are directly included in the operation, so it is unnecessary to load them into intermediate registers most of the time. c. Elimination of local common subforms: If there is a repeated calculation in the expression, the result of the first calculation is saved and will be used for subsequent calculations whenever possible, thus eliminating complicated calculations from the code. d. CASE/SWITCH statement optimization: optimize the CASE/SWITCH statement as a jump table or jump string.
Level 5 (Common subexpression elimination) optimizations include:
a. Global common subexpression elimination: Whenever possible, the same subexpression inside the function is only calculated once. Intermediate results are stored in a register in place of new calculations. b. Simple loop optimization: A loop that occupies a section of memory with a constant is optimized when it is running.
Level 6 (Loop rotation) optimization includes:
a. Loop loop: If the program code can be executed faster and more efficiently, the program loop will loop.
Level 7 (Extended Index Access optimizing) optimization includes:
a. Extended entry optimization: Use DPTR data pointers for register variables when appropriate, and pointer and array access are optimized to reduce program code and improve execution speed.
Level 8 (Reuse Common Entry Code) optimization includes:
a. Common tail merging: When there are multiple calls to the same function, some setting codes can be reused, thereby reducing the length of the program code.
Level 9 (Common Block Subroutines) optimizations include:
a. Common subroutine blocks: Detect repeatedly used instruction sequences and convert them into subroutines. C51 will even rearrange the code to have more reusable instruction sequences.
Two, C51 and ASM mixed programming technology
2.1 Significance of mixed programming
Usually use C51 to write the main program. However, it is more efficient to use assembler programming when some timing requirements are strict, so it is required to call some subroutines written in assembler language in the C program.
Method 1. Directly add “asm” precompilation pointer before each assembly statement in the function body.
void Test1(void)
{
asm MOV R1,#0AH
asm LOOP: INC A
asm DJNZ R0,LOOP
return;
}
Method 2. Use asm as a keyword and enclose it in curly braces for subsequent assembly
void Test2(void)
{
asm
{
MOV R1,#0AH
LOOP: INC A
DJNZ R0,LOOP
}
return;
}
Method 3: Embed the assembly code in the C module through the statement "#pragma"
void Test3 (void)
{
#pragma asm
MOV R1,#0AH
LOOP: INC A
DJNZ R0,LOOP
#pragma endasm
return;
}
3. Naming rules for common symbols in C51
3.1. Conversion rules between C51 function names and assembly program names
After the C51 program module is compiled into an object file, the function names in it will be converted into different function names according to the nature of their definitions. Therefore, it is required when C51 and assembly programs call each other The assembler must obey this conversion rule for function names.
3.2. Naming rules of C51 functions and their related sections
After a C51 source program module is compiled, each function in it is assigned to an independent CODE section with the naming rules of "? PR? Function name? Module name".
Note: If the "OVERLAYABLE" flag is added, it can be analyzed by the L51 connection/locator
4. Parameter passing rules of C51 function
Parameter transmission is realized through internal R1-R7, and up to three parameters can be transmitted.
The specific use is as follows:
五、 Data Overlay
Most C compiler function parameters and local variables are stored in a part of the hardware stack called a stack frame. The advantage of this method is that it is fast, and it is very practical for an architecture with a large stack space.
However, the 8051 stack space is only 256 bytes, this method is obviously not suitable, and it is too wasteful of the 8051 stack space.
Therefore, the C compiler for C51 uses the LX51 linker to store function parameters and local variables in fixed memory locations (fix memory) with well-defined names (so that function parameters are easy to pass and access).
The LX51 linker creates a Call-tree by analyzing the structure of the program, so that local variables and function parameters are placed in the data segment that can be overwritten. This technique is very useful and can provide the same access effect as traditional stack frames.
Call Tree structure diagram: