Procedure 1: unsigned char i; unsigned char sum; for(i=1,sum=0;i<11;i++) { sum+=i; } The assembly code is: C:0x0003 7F01 MOV R7,#0x01 C:0x0005 E4 CLR A C:0x0006 FE MOV R6,A C:0x0007 EF MOV A,R7 C:0x0008 2E ADD A,R6 C:0x0009 FE MOV R6,A C:0x000A 0F INC R7 C:0x000B BF0BF9 CJNE R7,#0x0B,C:0007 Code length (bytes): 11, execution cycle (machine cycle): 63 Procedure 2: unsigned char i; unsigned char sum; for(i=10,sum=0;i;i--) { sum+=i; } The assembly code is: C:0x000F 7F0A MOV R7,#0x0A C:0x0011 E4 CLR A C:0x0012 FE MOV R6,A C:0x0013 EF MOV A,R7 C:0x0014 2E ADD A,R6 C:0x0015 FE MOV R6,A C:0x0016 DFFB DJNZ R7,C:0013 Code length (bytes): 9, execution cycle (machine cycle): 53 Procedure 3: unsigned char i=11; unsigned char sum=0; while(i--) { sum+=i; } The assembly code is: C:0x0003 7F0A MOV R7,#0x0B C:0x0005 E4 CLR A C:0x0006 FE MOV R6,A C:0x0007 AD07 MOV R5,0x07 C:0x0009 1F DEC R7 C:0x000A ED MOV A,R5 C:0x000B 6005 JZ C:0012 C:0x000D EF MOV A,R7 C:0x000E 2E ADD A,R6 C:0x000F FE MOV R6,A C:0x0010 80F5 SJMP C:0007 Code length (bytes): 15, execution cycle (machine cycle): 130
From the above three different programs, we can see that the calculation results are all 0x37 (55), but the shortest code is 9, the longest code is 15, the fastest speed is 53, and the slowest speed is 130. It can be seen that the performance of the three programs is quite different.
How to write loop code with small space and high running efficiency? To write excellent loop code in C51 compilation environment, you must be familiar with the instruction system of 51 assembly language. Observe program 2, the loop control instruction uses DJNZ loop transfer instruction, which completes both counting and loop judgment operations at the same time, and only occupies two bytes. It is the most efficient loop instruction in the 51 instruction system. Therefore, when designing loop programs, C51 should use DJNZ in loop programs as much as possible. Of course, the number of loops of DJNZ instruction is fixed, and it is mainly used in the case of a fixed number of loops.
One of the biggest features of the DJNZ instruction is the decrement count, so the loop program must use the decrement method to compile the DJNZ instruction, such as the above program 2. Another feature of the DJNZ instruction is to decrement first and then judge, so the design of the loop program must also adhere to the principle of decrement first and then judge, otherwise the DJNZ instruction cannot be obtained, such as the above program 3. If program 3 is rewritten as:
unsigned char i=10;
unsigned char sum=0;
while(i)
{
sum+=i;
i--;
}
, the same assembly code as program 2 can be obtained. If there are other operations after i--, for example, change it to:
unsigned char i=10,j=0;
unsigned char sum=0;
while(i)
{
sum+=i;
i--;
j++;
}
also cannot get DJNZ assembly instruction, that is to say, during the execution of loop statement, decrement and judgment must be continuous, and decrement comes first and judgment comes later. For while loop, when decrement and judgment are combined into one step, while(--i) should be used. According to the above, do-while loop can also assemble DJNZ instruction, which will not be listed one by one.
However, when the loop variable is not completed by a constant assignment statement, but comes from another variable, the for and while statements cannot generate DJNZ instructions no matter what control flow they use, because both loops are control logics that are judged first and then executed, and the execution process of DJNZ is to execute the loop body first and then make loop judgments. According to the control flow of DJNZ, only the do-while statement meets this condition, so when the number of loops is not a constant but a variable, the do-while loop statement must be used.
In summary, if you want to use the DJNZ instruction to improve program efficiency, you should adhere to the following three principles when designing loop programs:
① Use decrement counting;
② Decrement first and then judge, and the decrement and judgment are performed continuously;
③ When the number of loops is a variable, use a do-while loop.
The 8051 microcontroller has two loop instructions, namely DJNZ Rn, rel and DJNZ direct, rel. For basic microcontrollers, the execution time of both is 2 machine cycles, but the instruction length of the two is different. The former occupies 2 bytes and the latter occupies 3 bytes. The loop program also involves the initialization operation of the loop variable. For the former, use MOV Rn, #XX, 2 bytes per cycle, and for the latter, use MOV direct, #XX, 3 bytes 2 cycles. Taking a single-layer loop as an example, using a working register saves 2 bytes and 1 cycle compared to a direct address. In addition, the more important performance difference between the two is that the latter requires an additional memory unit to be allocated. Because program modules usually use working registers as local variables, using working registers as loop variables will not increase memory usage. In short, using working registers as loop counters is an important principle that should be adhered to when designing loop programs.
Generally, the C51 compiler assigns the number of loops to the working register, such as
unsigned char i;
for(i=100;i;i--)
{
dosomething();
}
However, the result of C51 compilation is often unsatisfactory when one of the following situations occurs:
① The function dosomething is an externally defined C language function;
② Function dosomething is an external function with C language interface, which is implemented in assembly language and can be called by C program.
In the above two cases, loop variable i is stored in memory unit, that is, direct addressing is adopted. For local variable i, C51 compiler adopts direct address storage. The reason is that it is based on the assumption that, without any special treatment, C51 assumes that external function occupies all working registers. Therefore, these occupied registers cannot be modified outside the loop. C51 can only allocate loop control variables in memory address units. However, if only a few working registers are used in the loop body statement or even no working registers are used at all, the compiler still processes according to this assumption, then the compiler cannot show its efficiency. Fortunately, C51 provides a pseudo-instruction REGUSE to make up for this defect. The REGUSE pseudo-instruction is used to tell the compiler which registers or special function registers SFR are occupied by a function or subroutine. The compiler may allocate loop variables to registers not occupied by the loop body according to the register occupation information provided by the function, thereby achieving the purpose of optimizing the design.
In addition, one switch must be turned on, namely Global Register Coloring, by checking Project - Options for Target - C51 - Global Register Coloring.
In case ①, you should add code to the source file where the function dosomething is located (assuming that the function occupies A and B):
#pragma asm
$REGUSE dosomething(A,B)
#pragma endasm
After recompiling the project, you can see in the assembly window that the loop variable has used the working register.
In case ②, since it is an assembly program, you only need to add one line of code (assuming that the subroutine occupies A and B):
$REGUSE dosomething(A,B)
It can also be observed that the loop variable has been changed to the working register.
It should be noted that the register occupation mentioned here refers to the possibility or certain destruction of these registers during the execution of the function or subroutine, that is, the execution of write operations, and read-only registers should not be treated as occupied. In addition, the working registers used for parameter passing do not need to be specified.
Previous article:ADC0804+LED digital tube displays analog value 0~255
Next article:51 MCU bus driver
Recommended ReadingLatest update time:2024-11-15 14:55
- Popular Resources
- Popular amplifiers
- 西门子S7-12001500 PLC SCL语言编程从入门到精通 (北岛李工)
- Siemens Motion Control Technology and Engineering Applications (Tongxue, edited by Wu Xiaojun)
- How to read electrical control circuit diagrams (Classic best-selling books on electronics and electrical engineering) (Zheng Fengyi)
- MCU C language programming and Proteus simulation technology (Xu Aijun)
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- Sn-doped CuO nanostructure-based ethanol gas sensor for real-time drunk driving detection in vehicles
- Design considerations for automotive battery wiring harness
- Do you know all the various motors commonly used in automotive electronics?
- What are the functions of the Internet of Vehicles? What are the uses and benefits of the Internet of Vehicles?
- Power Inverter - A critical safety system for electric vehicles
- Analysis of the information security mechanism of AUTOSAR, the automotive embedded software framework
- A 39-year-old single programmer moves into a nursing home? The happiness of a programmer is beyond your imagination!
- Recruiting part-time MCU engineers (Dalian area)
- Import HFSS devices into AD to generate PCB files
- Problem with stack SP pointer
- This section needs urgent revision
- [NXP Rapid IoT Review] Rapid IoT Studio Display and Touch Applications
- How to write down what you want to express in your heart
- 【AT-START-F403A Review】+2.2' color TFT display driver
- Does anyone have a simulation circuit diagram of the LMD18200 chip?
- Digital Circuit Design with Verilog HDL.pdf