What is a subroutine?
In the actual programming process, in order to reduce the amount of program code, some frequently used instruction sets are called subroutines; this can be compared to the delay function delay() in C language, etc.
Function:
In order to solve the troublesome operation of repeatedly using the same set of program codes, just call it every time you need it;
Subroutine execution characteristics:
1. Called by other programs;
2. After execution, the execution flow needs to be returned to the main program of the subroutine;
~A gorgeous dividing line~~~
The above content is too simple. I believe that comrades who have learned a little bit of other languages can deeply understand it. Here we mainly focus on the explanation of assembly language; to explain the details that we often use high-level languages but habitually ignore (details are also functions that are directly optimized by high-level languages and are not seen)
Here comes the point!
Two points to note when calling a subroutine:
1. Protection and restoration of the site;
2. Transfer of parameters between main program and subprogram
Protection and restoration of the site
Let’s imagine a scenario:
Before calling a subroutine, a general unit (accumulator A) of the microcontroller stores a valuable data that will be used after the subroutine is executed. However, since this general unit is used when the subroutine is executed, the value is no longer found after exiting the subroutine.
Well, given this situation, we have the argument for protection and restoration;
Common units include: R0~R7, accumulator A, data pointer DPTR, flags and status, etc.;
Parameter passing
Passing parameters using accumulators
This method can directly "play the trick on the opponent". Anyway, the value is already in accumulator A, so it can be used directly in the subroutine. When the subroutine returns a value, it can also directly return the value to accumulator A.
For example:
/*Assume that the memory addresses 30H, 31H, 32H, and 33H are used to store the values of a, b, c, and d respectively. Now we need to divide d by a square + b square + c square */
ORG 0000H ; Set the program start storage address
START: MOV A,30H; Take the data at address 30H and send it to accumulator A
ACALL SQR; Call to check the square table (the square table is the array defined by the DB)
MOV R1,A; a square is temporarily placed in R1
MOV A,31H; take the value of b at address 30H and send it to accumulator A
ACALL SQR ;Call subroutine `Write code snippet here`
ADD A,R1 ;A=a方+b方
MOV R1,A ;R1 = A
MOV A,32H
ACALL SQR
ADDC A, R1
MOV 33H,A
SJMP $
;Subroutines
SQR: MOV DPTR,#TAB; assign the address of the first element of the square table to the DPTR data pointer
MOVC A,@A+DPTR; assign the corresponding data value in the TAB square table to accumulator A
RET; Subroutine return instruction. After execution, the two contents at the top of the stack are popped out and sent to the PC, and SP (stack top pointer) is reduced by 2; then the 16-bit address is placed in the PC;
TAB: DB 0,1,4,9,6,25,36,49,64,81; DB is a byte definition instruction, and each subsequent data occupies one byte;
END
Passing parameters using the stack
Here is a stack concept:
What is a stack: a storage area; a storage area opened up in the RAM;
Stack function: specially used to temporarily store data or return address;
What are the stack transfer parameters:
Using the stack to pass parameters is a method often used in subroutine nesting;
How to pass parameters:
Before calling a subroutine, use the PUSH instruction to push the data required by the subroutine into the stack.
When executing the subroutine, use the POP instruction to pop data from the stack;
For example:
/*question:
Write a subroutine for 0! +1! +2! +3! +4!
Unit 20H stores the number to be factored, and unit 30H stores the factorial calculated each time the subroutine is called.
The problem is on lines 30 and 31 of the program.
*/
ORG 0000H
MOV SP,#60H; Initialize SP=60H; Note that 60H here is an address instead of an integer;
MOV 20H,#0H; store the number to be factorialized;
MOV R2,#04H ;Number of cycles
MOV A,#0H
START: PUSH 20H; SP=SP+1, the integer 20H is given to the stack register at address 61H
PUSH ACC; SP = SP + 1, here the integer value stored in ACC is assigned to the register unit at address 62H, which should not be A but ACC
ACALL MU; call the subroutine at MU, SP=SP+2, and send the address of PC here to SP
POP ACC
POP 30H
ADD A,30H
INC 20H
DJNZ R2,START
SJMP $
MU: MOV R1,SP ; borrow R1 as stack pointer
DEC R1 ;Protect the scene when programming
DEC R1 ;Protect the scene when programming
DEC R1
DEC R1; R1 points to the number to be factorialized
MOV A,@R1; Take out the number to be factorial
ADD A,#02H ; ? Why does A need to be incremented by 2? Is it related to the program in line 31?
MOVC A,@A+PC; Lookup table? How does CP change from the top-down execution state to the table lookup state?
XCH A,@R1 ; Whole byte exchange
RET ; Return to the address of the main program
TAB: DB 0,1,2,6,24,120
END
Additional knowledge:
There was a problem in the above program code:
PUSH A
POP A
Error: Expression does not match
PUSH ACC
POP ACC
No error is reported;
wrong reason:
Although A and ACC are the same thing; but...PUSH and POP instructions must be followed by a direct address, but A is compiled into accumulator A (not address). When the compiler compiles, A is considered a register and ACC is considered a special function register (address); so an error is reported;
Previous article:Teach you how to learn 51 single chip microcomputer: learn the basic knowledge of hardware
Next article:Notes on assembly operators based on the MCS-51 kernel
Recommended ReadingLatest update time:2024-11-16 13:48
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Development board based on TI AM5728 (floating point dual DSP C66x + dual ARM Cortex-A15)
- Agitek High-tech Joint Electronics Laboratory fully supports the National Undergraduate Electronics Design Competition
- Can the microcontroller detect negative values if it is powered by a single power supply?
- Signals and Systems (3rd Edition)
- Can a 100A current flow through a PCB? Tips for setting up high current paths
- hcnr201 isolation circuit problem
- recruitment
- KiCad 6.0.0 released
- RF front-end outsourcing
- Boot hardware settings