Detailed analysis of KEIL C51 code optimization: local parameters placed in register variables, data coverage technology

Publisher:闪耀的星空Latest update time:2022-06-01 Source: eefocusKeywords:KEIL Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

After reading an article titled "Keil C51's method of continuously reading the same port" (original text) in the "Experience Exchange" column of "Microcontroller and Embedded System Application" magazine, issue 10, 2005, the author believes that the article does not provide an in-depth and accurate analysis of this issue. The two solutions mentioned in the article are not direct and simple. The author believes that this is not a problem that Keil C51 cannot handle continuous reading and writing of a port, but a problem that the user is not familiar enough with the use of Kei1 C51 and the design is not detailed enough, so this article is written.


This article proposes three different solutions to the problems mentioned in the original article. Each method is more direct and simpler than the method mentioned in the original article, and the design is more standardized. (No criticism intended, please forgive the original author)


1 Problem Review and Analysis
The original article mentioned: In actual work, when the same port was read repeatedly and continuously, the Keil C51 compilation did not achieve the expected results. The original author analyzed the assembly program compiled by C and found that the second read statement for the same port was not compiled. Unfortunately, the original author did not analyze the reason for the failure to compile, but hurriedly used some less standardized methods to test out two solutions.

For this problem, it is easy to find out by reading the manual of Keil C51: KeilC51 compiler has an optimization setting. Different optimization settings will produce different compilation results. Generally, the default compilation optimization setting is set to level 8 optimization, and the actual maximum can be set to level 9 optimization:


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. 
The above problems are caused by Keil C51 compiler optimization. Because in the original program, the peripheral address is directly defined as follows:
unsigned char xdata MAX197 _at_ 0x8000
. The variable MAX197 is defined to the external extended RAM address 0x8000 using _at_. Therefore, Keil C51 optimized compilation naturally thinks that repeating the second read is useless, and the result of the first read can be used directly, so the compiler skips the second read statement. At this point, the problem is clear at a glance.


2 Solution
Based on the above analysis, it is easy to come up with a good solution.
2.1 The simplest and most direct solution
The program does not need to be modified at all. Just set the compilation optimization selection of Keil C51 to 0 (no optimization). Select the Target in the project window, then open the "Options for Target" setting dialog box, select the "C51" tab, and select "Level" in "Code Optimiztaion" as "0: Costant folding". After compiling again, you will find that the compilation result 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
Both read operations are compiled.


2.2 The best way
is to tell Keil C51 that this address is not a general extended RAM, but a connected device with "volatile" characteristics, and each read is meaningful. You can modify the variable definition and add 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", and then modify the variable in the program and define it as a direct address:
#define MAX197 XBYTE[0x8000]

In this way, the Keil C51 settings can still retain advanced optimization, and in the compilation results, the same two reads will not be skipped by optimization.


2 3 Hardware Solution
In the original text, the data of MAX197 is directly connected to the data bus, and the address bus is not used. A port line is used to select the high and low bytes. A very simple modification method is to use an address line to select the high and low bytes. For example: connect P2.0 (A8) to the HBEN pin (pin 5 of MAX197) that was originally connected to P1.0. Define the operation addresses of the high and low bytes in the program respectively:
unsigned char volatile xdata MAX197_L _at_ 0x8000;
unsigned char volatile xdata MAX197_H _at_ 0x8100;
Change the original program:
MAXHBEN = 0;
down8 = MAX197; // read the lower 8 bits
MAXHBEN = 1;
up4 = MAX197; // read the upper 4 bits
to the following two sentences
down8 = MAX197_L; // read the lower 8 bits
up4 = MAX197_H; // read the upper 4 bits


3 Summary
After long-term testing and improvement and the actual use of a large number of developers, Keil C51 has overcome most of the problems, and its compilation efficiency is also very high. For general use, it is difficult to find any problems. The author has roughly studied the results of Keil C51 optimization compilation. I admire the wisdom of Keil C51 designers very much. The assembly code generated by the compilation of some C programs is even better and more concise than the code written directly by ordinary programmers in assembly language. By studying the assembly code generated by Kell C51 compilation, it is very helpful to improve the level of assembly language programming.

From the problems in this article, we can see that when we encounter problems in design, we must not be blinded by superficial phenomena and rush to solve them. We should carefully analyze and find out the causes of the problems. Only in this way can we solve the problems fundamentally and thoroughly.

 

 

Appendix: Optimization levels and optimization effects in Keil C51

level

illustrate

0

Constant merging: The compiler pre-calculates results and replaces expressions with constants whenever possible. This includes running address calculations.
Optimizing simple accesses: The compiler optimizes access to internal data and bit addresses of the 8051 system.
Jump optimization: The compiler always expands jumps to the final target, and multi-level jump instructions are removed.

1

Dead code removal: Unused code segments are removed.
Reject jumps: Conditional jumps are carefully checked to determine whether they can be improved or removed by inverting the test logic.

2

Data Coverage: Data and bit segments suitable for static coverage are determined and internally identified. The BL51 connector/locator can select segments that can be covered through global data flow analysis.

3

Peephole optimization: Eliminate redundant MOV instructions. This includes unnecessary loads from storage and constant load operations. When storage space or execution time can be saved, replace complex operations with simple operations.

4

Register variables: Automatic variables and function parameters are allocated to registers if possible. The storage area reserved for these variables is omitted.
Optimized extended access: Variables of IDATA, XDATA, PDATA and CODE are directly included in the operation. Most of the time, there is no need to use intermediate registers.
Local common subexpression elimination: If the same calculation is repeated with an expression, the result of the first calculation is saved and may be used later. Redundant calculations are eliminated.
Case/Switch optimization: Code containing SWITCH and CASE is optimized to jump tables or jump queues.

5

Global common subexpression elimination: The same subexpression within a function may be calculated only once. Intermediate results are stored in registers and used in a new calculation.
Simple loop optimization: Loop programs that fill storage areas with a constant are modified and optimized.

6

Loop Optimization: The program optimizes loops if the resulting program code is faster and more efficient.

7

Extended index access optimization: Use DPTR for register variables when appropriate. Optimize execution speed and code size for pointer and array access.

8

Common tail merging: When a function has multiple calls, some setup code can be reused, thus reducing program size.

9

Common Block Subroutines: Detects looping instruction sequences and converts them into subroutines. Cx51 even rearranges the code to get larger looping sequences.


Keywords:KEIL Reference address:Detailed analysis of KEIL C51 code optimization: local parameters placed in register variables, data coverage technology

Previous article:KEIL C51 general register parameter passing rules
Next article:51 MCU local variables occupy RAM problem

Recommended ReadingLatest update time:2024-11-17 06:01

Single chip microcomputer control traffic light c51 program
First picture /* Program effect: The single-chip microcomputer simulates the traffic light control program, and the rules are as follows: when the north and south are open to traffic, the green light on the north and south is on, and the red light on the east and west is on. Then
[Microcontroller]
Single chip microcomputer control traffic light c51 program
Why is the align address used when Keil compiles the cortex-m3 pure assembly?
  When compiling the following code: STACK_TOP   EQU 0x20002000       AREA    Reset,CODE,READONLY       DCD 0x20002000       DCD Start       ENTRY   ;   CODE16       Start       ldr r2,=Test       LDRD r0,r1,        LDRD r0,r1,        LDRD r0,r1,    ;   movs    r0,r0   ;   NOP   ;   align 4   Test  
[Microcontroller]
Why is the align address used when Keil compiles the cortex-m3 pure assembly?
How to implement soft reset in C51?
You can define a function pointer to the reset vector (0x0000), and then call the function where a soft reset is required in the C program: ((void (code *) (void)) 0x0000) (); For example, the following program constantly resets: void reset (void) {   ((void (code *) (void)) 0x0000) (); } void main (void) {   r
[Microcontroller]
Implementation of ASM51 calling C51 function
        MCS-51 series microcontrollers will be the mainstream microcontrollers in my country at present and for a considerable period of time in the future. However, in the early development process, programmers had to start from the profound assembly language, and developers were required to have a considerable unders
[Microcontroller]
KEIL/MDK generates BIN files
Generated using relative paths, no modification required $KARMARMCCbinfromelf.exe --bin --output=@L.bin !L  After compiling, you can see the following in the Build Out box:  After Build - User command #1: D:Program FilesMDK516ARMARMCCbinfromelf.exe --bin --output=test1.bin .objtest1.axf After the above operation,
[Microcontroller]
How to realize communication between C51 microcontroller and PLC
1. HMI (Human Machine Interface) is increasingly used in industrial automation systems and equipment due to its small size, high performance, and strong real-time characteristics. It has different displays such as letters, Chinese characters, graphics and pictures, and the interface is simple and friendly. Equipped
[Microcontroller]
[C51 Getting Started Notes] IIC bus + E2PROM chip (24C02)
Common bus technologies: The use of serial bus technology can greatly simplify the hardware design of the system, reduce the size of the system, and improve reliability. At the same time, the system can be easily modified and expanded. Commonly used serial expansion buses include: I2C (Inter IC BUS) bus, single bu
[Microcontroller]
[C51 Getting Started Notes] IIC bus + E2PROM chip (24C02)
Header file of STC microcontroller in KEIL compiler
How to deal with the problem that the header file of the STC microcontroller cannot be found in the Keil compiler. First, find an upgrade package for the STC microcontroller on the Internet. After installing it, you can see that there are STC model microcontrollers to choose from. However, at this time, i
[Microcontroller]
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号