In the GPIO experiment, we first wrote an assembly program to operate the register to light up the LED. However, the readability and portability of assembly language are too poor, so we wrote the startup code, set the stack pointer SP, and then called the main function in C language to enter the world of C language. The C language accessed the control register and lit up the LED. The readability and portability of the program were greatly improved. So, have we ever thought about how to call the C language entry function main in assembly language?
In fact, for ARM processors, the rules for subroutine calls are formulated in the ARM instruction set assembler and the THUMB instruction set assembler - the ATPCS rules, which include:
Register Usage Rules
Data stack usage rules
Parameter passing rules
There are 16 registers R0-R15 in the ARM processor. Each register has a usage specified by the ATPCS rules and an alias specified according to its usage, as shown in the following table:
register | Aliases | use |
---|---|---|
R15 | pc | Program Counter |
R14 | 1. | Link register (used to store subroutine return address) |
R13 | sp | Data stack pointer (pointing to the top of the stack) |
R12 | ip | The scratch register for the subroutine call |
R11 | v8 | ARM state local variable register 8 |
R10 | v7 | ARM state local variable register 7 |
R9 | v6 | ARM state local variable register 6 |
R8 | v5 | ARM state local variable register 5 |
R7 | v4 | ARM state local variable register 4 |
R6 | v3 | ARM state local variable register 3 |
R5 | v2 | ARM state local variable register 2 |
R4 | v1 | ARM state local variable register 1 |
R3 | a4 | Parameter/result/scratch register 4 |
R2 | a3 | Parameter/result/scratch register 3 |
R1 | a2 | Parameter/result/scratch register 2 |
R0 | a1 | Parameter/result/scratch register 1 |
Summarized as follows:
Parameters are passed and results are returned between subroutines through registers R0-R3;
In the subroutine, local variables are saved through registers R4-R11;
Register R12 is used as the scratch register between subroutines;
Register R13 is used as a data stack pointer, pointing to the top of the stack;
Register R14 is used as a link register to store the return address of the subroutine;
Register R15 is used as the program counter;
ATPCS stipulates that the data stack is of FD type (Full Descending), that is, the stack pointer points to the top element of the stack and grows in the direction of decreasing memory address. During operation, the data stack is 8-byte aligned, and the stmdb/ldmia batch memory access instructions are used to operate the FD data stack.
The FD type data stack operates specifically as follows:
When saving content, first decrement the SP pointer and then save the data;
When restoring data, first obtain the data and then increment the SP pointer;
When calling a function, if there are no more than 4 parameters, they are passed in sequence using R0-R3. If there are more than 4 parameters, the remaining parameters are passed through the data stack.
When a function returns a result, it is passed in sequence using R0-R3;
Experiment - Experiment on passing parameters when calling functions in assembly
1. Purpose
Calling functions in assembly language and passing parameters.
2. Experimental content
The main function defines the parameters. If the passed parameter is 1, the first LED is turned on. If the passed parameter is 2, the second LED is turned on.
3. Experimental Code
3.1. Startup Code
@ brief: S3C2440 startup file
@ author: mculover666
.text
.global _start
_start:
@ Disable watchdog
LDR R0,=0x53000000
MOV R1,#0
STR R1,[R0]
@ Set the stack top pointer SP (start from Nand)
LDR SP,=4096
@ Call led_on with parameter 1 to turn on the first LED
LDR R0,=1
BL led_on
@ Pass parameter 100000, call delay, delay
LDR R0,=100000
BL delay
@ Call led_on with parameter 2 to turn on the second LED
LDR R0,=2
BL led_on
@ Program Pause
halt:
B halt
3.2.C code
void delay(volatile int xms)
{
while(xms--);
}
int led_on(int led)
{
if(led == 1)
{
/* Set the GPFCON register to configure the GPF4 pin as output mode*/
*(unsigned int *)0x56000050 &= ~(3<<(2*4));
*(unsigned int *)0x56000050 |= 1<<(2*4);
/* Set the GPF DAT register, GPF4 outputs low level, and lights up the LED */
*(unsigned int *)0x56000054 &= ~(1<<4);
}
else if(led == 2)
{
/* Set the GPFCON register to configure the GPF4 pin as output mode*/
*(unsigned int *)0x56000050 &= ~(3<<(2*5));
*(unsigned int *)0x56000050 |= 1<<(2*5);
/* Set the GPF DAT register, GPF4 outputs low level, and lights up the LED */
*(unsigned int *)0x56000054 &= ~(1<<5);
}
return 0;
}
3.3. Compilation
TARGET = led_blink
CFLAGS = -Wall # Output all warnings
$(TARGET).bin:$(TARGET).elf
arm-linux-objcopy -O binary -S $(TARGET).elf $(TARGET).bin
#Note: The startup file must be linked first
$(TARGET).elf:start.o $(TARGET).o
arm-linux-ld -Ttext 0 start.o $(TARGET).o -o $(TARGET).elf
$(TARGET).o:$(TARGET).c
arm-linux-gcc -c $(TARGET).c $(CFLAGS) -o $(TARGET).o
start.o:start.s
arm-linux-gcc -c start.s $(CFLAGS) -o start.o
clean:
rm -rf *.o *.elf *.bin
download_to_nand:
#Download to nand flash
oflash 0 1 0 0 0 $(TARGET).bin
4. Download and run
The program starts running and the first LED lights up:
After a delay of about 1s, the second LED is also lit:
5. Experimental Summary
Through this experiment, we have mastered the use of ATPCS rules in actual development. When calling the main function, we use the R0 register to pass parameters, which is summarized as follows:
The subroutine calling rules in ARM processors are formulated by ATPCS, including register usage rules, data stack usage rules, and parameter passing rules;
R0-R3 can pass parameters/results, R4-R11 can store local variables, R13 is the data stack pointer SP, and R14 stores the subroutine return address;
The data stack in ATPCS is of FD type, i.e. full-decreasing type;
In ATPCS, parameters are passed in sequence using R0-R3. If there are more than 4 parameters, the rest are passed using the data stack.
Previous article:S3C2440-Bare Metal Edition-03 | Use of GPIO (lighting up LEDs, key detection)
Next article:S3C2440-Bare Metal Edition-05 | Detailed Explanation of S3C2440 Clock System (FCLK, PCLK, HCLK)
Recommended ReadingLatest update time:2024-11-16 11:49
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
- Load switch controls battery voltage output more reliably and simply than MOS
- EEWORLD University Hall----Why is the embedded microprocessor architecture design so complicated?
- CC2640R2f Watchdog
- MSP430F5438A
- Could you recommend a replacement chip for PGA280?
- 180,000 for 5 kicks? What kind of screen is this? It's so expensive! Is there gold in the screen?
- Evaluation summary: Xingkong Board Python programming learning control board
- National epidemic statistics in the past 11 days, please pay attention if you are visiting relatives
- Problems encountered during ads2020 installation
- MSP430 MCU Simulation Example 19-D/A Conversion Sine Wave Generator Based on Proteus