1. Code
Previously, I learned how to use C language to light up the LED on an ARM bare metal machine. I learned that in an ARM program, the main function needs an assembly instruction to boot itself. The function of the assembly instruction is to set the stack address, that is, to indicate the storage address of the program; and to boot the main function.
Here we use this program to analyze the internal mechanism of C program execution in ARM and the storage location of the program in the stack.
Below is the source code of the C program, the assembly instructions for the boot, and the disassembly file produced by cross-compilation:
C:
int main()
{
unsigned int *pGPFCON = (unsigned int *)0x56000050;
unsigned int *pGPFDAT = (unsigned int *)0x56000054;
/* Configure GPF4 as output pin */
*pGPFCON = 0x100;
/* Set GPF4 output to 0 */
*pGPFDAT = 0;
return 0;
}
Assembly instructions:
.text
.global _start
_start:
/* Set up memory: sp stack */
ldr sp, =4096 /* nand start */
// ldr sp, =0x40000000+4096 /* nor start*/
/* Call main */
bl main
halt:
b halt
Disassembler:
Disassembly of section .text:
/*Address*/ /*Machine code*/ /*Assembly instruction*/
00000000 <_start>:
0: e3a0da01 mov sp, #4096 ; 0x1000
4: eb000000 bl c 00000008 8: eafffffe b 8 0000000c c: e1a0c00d mov ip, sp 10: e92dd800 stmdb sp!, {fp, ip, lr, pc} 14: e24cb004 sub fp, ip, #4 ; 0x4 18: e24dd008 sub sp, sp, #8 ; 0x8 1c: e3a03456 mov r3, #1442840576 ; 0x56000000 20: e2833050 add r3, r3, #80 ; 0x50 24: e50b3010 str r3, [fp, #-16] 28: e3a03456 mov r3, #1442840576 ; 0x56000000 2c: e2833054 add r3, r3, #84 ; 0x54 30: e50b3014 str r3, [fp, #-20] 34: e51b2010 ldr r2, [fp, #-16] 38: e3a03c01 mov r3, #256 ; 0x100 3c: e5823000 str r3, [r2] 40: e51b2014 ldr r2, [fp, #-20] 44: e3a03000 mov r3, #0 ; 0x0 48: e5823000 str r3, [r2] 4c: e3a03000 mov r3, #0 ; 0x0 50: e1a00003 mov r0, r3 54: e24bd00c sub sp, fp, #12 ; 0xc 58: e89da800 ldmia sp, {fp, sp, pc} Disassembly of section .comment: /* Comments */ 00000000 <.comment>: 0: 43434700 cmpmi r3, #0 ; 0x0 4: 4728203a undefined 8: 2029554e eorcs r5, r9, lr, asr #10 c: 2e342e33 mrccs 14, 1, r2, cr4, cr3, {1} 10: Address 0x10 is out of bounds. 2. Knowledge Reserve 1.ARM assembly instructions For a detailed introduction to ARM assembly instructions, see another blog: Link First, let's make a brief introduction to assembly instructions: This starts with the CPU. The recognizable language of the computer is machine code, which is binary. The CPU can recognize and execute programs written in machine code. This development method is too complicated and difficult to master, so there are assembly instructions. Assembly instructions are actually a package of machine code. Assembly instructions can be converted into machine code after compilation, but compared to machine code, assembly instructions can be directly read and understood by people. An assembly instruction in ARM can be converted into 32-bit machine code. The machine code executed by ARM's CPU at a time is 32 bits, which means that ARM can process one assembly instruction at a time. Under the control of the controller, the CPU can read and write data in the memory to the registers inside the CPU (such as r0, r1, sp, pc, lr...), and then the arithmetic unit will perform operations on the values in the registers, including addition, subtraction, multiplication, division and logical operations, and the results can be written to the specified registers. The CPU can also jump to execute according to instructions, that is, jump to a specified memory address to fetch instructions for execution. The operation of the computer is supported by such high-speed and repeated simple operations of the CPU. So the general process of assembly instructions is as follows: the programmer writes assembly instructions, which are compiled into machine code, the machine code is stored in memory, the CPU reads and writes memory, and the CPU executes the machine code (assembly instruction). As shown in the figure, the CPU registers: 2. Register knowledge Parameters are passed between subroutines through registers r0~r3 lr originally holds the return address of the subroutine. When the value of lr is stored in the data stack, lr can have other uses. sp is the data stack pointer. It must be the same when entering and exiting a subroutine. sp always points to the top of the stack. PC is used as a program counter and cannot be used for other purposes ip is the scratch register called inside the subroutine 3. Code Analysis The assembly instructions of the boot code have two functions: setting up the stack and booting the function Setting up the stack is to use the sp (Stack Pointer) stack pointer, which is the stack top pointer. sp always points to the top of the stack, and the memory space where the program runs is in the allocated stack space. The boot function is to guide ARM to the memory space where the function written in C language is stored to execute the function written in C language (in the form of machine code in memory). The boot uses the jump command bl, which can make ARM jump to the specified memory address and copy the address of the next instruction to the lr register so that after calling the function, it can return to the calling point and continue to execute the next instruction. You can use the mov pc, lr instruction to return to the next instruction before the call and continue execution. 1. Instruction analysis The following is a detailed analysis of each assembly instruction: First instruction: mov ip, sp It saves the current stack top pointer sp to ip. Second instruction: stmdb sp!, {fp, ip, lr, pc} First, sp is shifted down 4Byte from the top of the stack of 4096 (db: shift first, then store), and then the current value of the pc register is stored in the memory address of 4092. Note that the address of the current instruction is 0X10, so the current value of pc is: 0X18 (ARM pipeline execution instruction); Then, sp moves down 4 bytes from the memory address of 4092, and stores the value of the lr register at the memory address of 4088. The lr register stores the scene when the assembly instruction calls the main function, that is, the instruction at memory address 8. Then, sp moves down 4 bytes from the memory address of 4088, and stores the value of the ip register at the memory address of 4084. The ip register stores the original stack top pointer address, which is 4096. Then, sp moves down 4 bytes from the memory address of 4084, and stores the value of the fp register at the memory address of 4080. Finally, the memory address pointed to by sp is the address that was modified last, which is 4080. The stack situation at this time is as shown below: The third instruction: sub fp, ip, #4 Put the result of ip-4Byte into fp, which is the memory address of 4096-4=4092 (ip stores the original stack top pointer pointing to 4096), and fp points to the memory address of 4092. Fourth directive: sub sp, sp, #8 Here, the memory address pointed to by sp is reduced by 8 bytes, that is, 8 bytes of space are freed up after the memory address storing the four register information, which is exactly the space for two instructions, leaving space for storing two local variables later. The fifth and sixth instructions: mov r3, #1442840576 ; 0x56000000 add r3, r3, #80 ; 0x50 str r3, [fp, #-16] Store 0X56000050 into the r3 register. The seventh directive: str r3, [fp, #-16] Write the content of r3, that is, the local variable 0X56000050, to the address of fp-16Byte. The memory address of fp-16Byte is exactly the memory address immediately following the first four registers. It can be seen that the local variables of the calling function are stored after these four basic information registers. The eighth, ninth and tenth instructions: mov r3, #1442840576 ; 0x56000000 add r3, r3, #84 ; 0x54 str r3, [fp, #-20] These three instructions have the same meaning as the three instructions above, which are to store local variables in memory, and store 0X56000054 right below 0X56000050. Note that the sp stack pointer is next to the local variable. At this time, the stack situation is as shown below: Eleventh Directive: ldr r2, [fp, #-16] Read 0X56000050 into the r2 register. Article 12: mov r3, #256 ;0X100 Write 0X100 to the r3 register. Article 13: str r3, [r2] Write 0X100 to the memory space at address 0X56000050, that is, write it to the GPFCON register, and configure the GPF4 pin mode to output. Instructions 14, 15 and 16: ldr r2, [fp, #-20] mov r3, #0 ; 0x0 str r3, [r2] Same as above, write 0 into the GPFDACT register, light up the LED corresponding to GPF4, and the GPF4 pin outputs a low level. Articles 17 and 18: mov r3, #0 ; 0x0 mov r0, r3 Clearing the r0 register is equivalent to return 0 in the main function. The r0, r1, r2, and r3 registers are used to pass parameters between subroutines. Article 19: sub sp, fp, #12 Re-point sp to the address of fp-12Byte, which is 4080. Article 20: ldmia sp, {fp, sp, pc} Restore registers from the stack First, sp reads 4Bytes from the current address 4080, which is the address where fp is first saved, and writes it into fp. Then, sp moves up 4Byte from the memory address of 4080, which is 4084, reads 4Bytes, and writes to sp, which means writing the previous ip value (4096) to sp Then, sp moves up 4Byte from the memory address of 4084, which is 4092, reads 4Bytes, and writes to pc, which is to write the previous lr value (the address of the assembly boot main) to pc, which is 8, and the program jumps back to the address of 0X8, which is the return of main. 2. Overall analysis It can be seen that the 4K space includes: register initial values, local variables, and code segments. The 4K memory is sufficient for the program to run. Let's make a brief summary: The code segment will be saved behind the stack The beginning of the stack saves the original registers: pc, lr, ip, fp, to ensure that the function can be returned to the original position after calling The value of sp must be the same when entering and exiting the subroutine.
Previous article:S3C2440—4. Clock system
Next article:Detailed explanation of embedded ARM assembly
- Popular Resources
- Popular amplifiers
- 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
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- Infineon's PASCO2V15 XENSIV PAS CO2 5V Sensor Now Available at Mouser for Accurate CO2 Level Measurement
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- A new chapter in Great Wall Motors R&D: solid-state battery technology leads the future
- Naxin Micro provides full-scenario GaN driver IC solutions
- Interpreting Huawei’s new solid-state battery patent, will it challenge CATL in 2030?
- Are pure electric/plug-in hybrid vehicles going crazy? A Chinese company has launched the world's first -40℃ dischargeable hybrid battery that is not afraid of cold
- This is a brain teaser - hypotenuse, leg, chord, even Pythagorean theorem
- Should the PCB trace angle not be 90°? — PCB Layout Tips
- Problems with serial programming of STC89C51RC microcontroller
- 【ST NUCLEO-H743ZI Review】+ 2. LED Flowing Light
- [National Day Self-driving Tour] - There are mountain and water routes, please recommend
- PIC16F15324 microcontroller serial port interrupt cannot enter
- High-speed PCB design technology (Chinese)
- A case of SPI communication malfunction
- EEWORLD University Hall----On-time Atom LWIP Video Tutorial
- C6000TM Multicore DSP + Arm SoC Open Source