Gcc related operating principles and program memory allocation issues under buntu and stm32

This article mainly introduces the program memory allocation problem under Ubuntu and stm32, as well as the address allocation problem of heap, stack, global, local and other variables.

Table of Contents

Preface

1. Task requirements

2. Experimental process

2.1 Learn and master the compilation and assembly process of executable programs

2.1.1gcc generates executable dynamic static libraries

2.1.2 Generate static and dynamic files and link them

2.2Gcc is not fighting alone. Please explain the purpose of each software in the gcc compilation tool set and understand the EFF file format

1. Install gcc under Linux system

2. Create main.c

3. Carry out pre-processing process

4. Compilation process

6. Dynamic linking and static linking

2.3 Program memory allocation issues under Ubuntu and stm32

2.31 Global variables & local variables

2.32 Heap & Stack

2.33 Programming verification in Ubuntu (x86) system and STM32 (Keil)

2.33. Ubuntu running

2.34, Keil operation

3. Result analysis (still thinking)

4. Summary

5. References


Foreword

A normal program is usually divided into three parts in memory: program segment, data segment, and stack.
The program segment contains the machine code and read-only data of the program. This segment is usually read-only, and writing to it is illegal.
The data segment contains static data in the program.
The stack is a contiguous block of memory. A register called the stack pointer (SP) points to the top of the stack. The bottom of the stack is a fixed address. One characteristic of the stack is that it is last in, first out. That is to say, the data put in later is taken out first. It supports two operations, PUSH and POP. PUSH is to put the data on the top of the stack, and POP is to take the data from the top of the stack. Dynamic data is stored on the stack.

1. Task requirements

1. Learn and master the compilation and assembly process of executable programs. The learning tasks are as follows:

1) Read, understand and study the materials “Using gcc to generate static libraries and dynamic libraries.pdf” and “Generation and use of static library .a and .so library files.pdf”, please copy them faithfully under the Linux system (Ubuntu) Again.

2) Adapt the program code of the first job. In addition to the x2x function, expand and write an x2y function (customized function). The main function code will call x2x and x2y; write these three functions as separate 3 .c files were compiled into 3 .o target files using gcc; use the ar tool to generate 1 .a static library file for the x2x and x2y target files, and then use gcc to combine the target file of the main function with this static library file Link, generate the final executable program, and record the file size.

3) Use the ar tool to generate a .so dynamic library file for the x2x and x2y target files, and then use gcc to link the target file of the main function with this dynamic library file to generate the final executable program, record the size of the file, and Compare with before.

2. Gcc is not fighting alone. Please explain the purpose of each software in the gcc compilation tool set and understand the EFF file format. The learning tasks are as follows: read, understand and study the materials “Linux GCC Common Commands.pdf” and “The Story Behind the GCC Compiler.pdf” and copy them truthfully.
3. Write a C program, review the concepts of global variables, local variables, heap, stack and other concepts, and program and verify them in Ubuntu (x86) system and STM32 (Keil) respectively (STM32 printf information to the host computer serial port assistant through the serial port) .
Summarize the allocation addresses of heap, stack, global, local and other variables in C programs under Ubuntu and stm32, and conduct comparative analysis.

2. Experimental process

2.1 Learn and master the compilation and assembly process of executable programs

2.1.1gcc generates executable dynamic static libraries

1. Create hello.h, hello.c and main.c files and enter the following code

Program 1: hello.h #ifndef HELLO_H #define HELLO_H void hello(const char *name);
 #endif //HELLO_H Program 2: hello.c #include <stdio.h> void hello(const char *name) { printf("Hello %s!\
", name); } Program 3: main.c #include "hello.h" int main() { hello("everyone"); return 0; }

2. Compile hello.c into .o file

gcc -c hello.c

3. Create a static library

Use the ar command to create a static library. Typing the following command at the system prompt will create the static library file libmyhello.a

ar -crv libmyhello.a hello.o

4. Use static database in the program

gcc -o main main.c libmyhello.a

5. Create s file

gcc -c -fpic hello.c gcc -shared *.o -o libsofile.s

6. The program uses dynamic libraries

mv libsofile.so /user/lib idconfig

Compile and run, and an error occurs in the program.

Solution: Copy the file libmyhello.so to the directory

1. Create sub1.h, sub2.h, main.c, sub1.c, sub2.c files:

The corresponding file contents are as follows:

sub1.h:
#include<stdio.h>

int add(int a,int b);

sub2.h:
#include<stdio.h>

int minux(int a,int b);

sub1.c:
#include"sub1.h"

int add(int a,int b){
        return a + b;
}

sub2.c:
#include"sub1.h"

int minus(int a,int b){
        return a-b;
}

main.c:
#include<stdio.h>
#include"sub1.h"
#include"sub2.h"

int main()
{
   int a =1,b =2;
   int c = add(a,b);
   int d = minus(a,b);
   printf("%d\
",c);
   printf("%d",d);
   return 0;
}

2. Generate static library a

gcc -c sub1.c sub2.c

ar crv libafile.a sub1.o sub2.o

Create an executable program using an .a file and execute it

gcc -o main main.c libafile.a ./main

Result: 3, -1

Dynamic library .so file usage

Generate target file

gcc -c -fpic sub1.c sub2.c

Generate shared .so file

gcc -shared *.o -o libsofile.so

Use .so library files to create executable programs

gcc -o test main.c libsofile.so ./test

An error occurred in the program!

Solution: Only search for the corresponding .so file under /lib and /usr/lib, so you need to copy the corresponding so file to the corresponding path.

sudo cp libsofile.so /user/lib

2.2Gcc is not fighting alone. Please explain the purpose of each software in the gcc compilation tool set and understand the EFF file format

1. Install gcc under Linux system
yum install gcc
2. Create main.c
vi main.c

The content of the main.c file is as follows

#include <stdio.h> //This program is very simple, it just prints a Hello World string. int main(void) { printf("Hello World! \
"); return 0; }
3. Perform preprocessing process

Convert main.c to main.i file

gcc -E main.c -o main.i
4. Compilation process

We further process the main.i file obtained from the main.c file we processed to obtain the main.s file.

gcc -S main.i -o main.s

5. Compilation

Convert main.s file to main.o file

gcc -c main.s -o main.o -v

(1) Static linking means directly adding the static library to the executable file during the compilation phase, so the executable file will be larger. The linker copies the function code from its location (in a different object file or static link library) into the final executable program. To create an executable file, the main tasks that the linker must complete are: symbol resolution (associating symbol definitions and references in the object file) and relocation (corresponding symbol definitions to memory addresses and then modifying all references to symbols) ).

(2) Dynamic linking means that only some description information is added during the linking stage, and the corresponding dynamic library is loaded from the system into the memory when the program is executed.

Perform dynamic linking

gcc main.c -o main

Perform static linking

gcc -static main.c -o main

Use the ldd command to check whether the dynamic library is linked

ldd main

Program memory allocation problem under 2.3Ubuntu and stm32

2.31 Global Variables & amp; Local Variables

Global variables
Variables defined outside all functions are called global variables, and their scope is the entire program by default, that is, all source files.

Local variables
Variables defined inside a function are called local variables (Local Variable). Its scope is limited to the inside of the function. If it leaves the inside of the function, it is invalid, and an error will be reported if it is used again.

2.32Heap & Stack

1. Stack in STM32
The microcontroller is an integrated circuit chip that integrates functions such as CPU, RAM, ROM, various I/O ports, interrupt system, timer/counter, etc. The CPU includes various bus circuits, calculation circuits, logic circuits, and various registers.

stm32 has general registers R0-R15 and some special function registers, including the stack pointer register.
When stm32 is running the program normally, and an interrupt occurs, the CPU needs to push the value in the register onto the RAM, and then store the address of the data in the stack register.
When the interrupt processing is completed and exited, the data is popped out of the stack into the previous register. This is done automatically in the C language.

2. Program memory allocation
The memory occupied by general programs is divided into the following parts:

1. Stack area (stack) – automatically allocated and released by the compiler, storing function parameter values, local variable values, etc. It operates like a stack in a data structure.

2. Heap area (heap) – Generally allocated and released by the programmer. If the programmer does not release it, it may be recycled by the OS when the program ends. It is different from the heap in the data structure, and the allocation method is similar to a linked list.

3. Global area (static area) (static) – global variables and static variables are stored together. Initialized global variables and static variables are in the same area, and uninitialized global variables and uninitialized static variables are in the same area. Another adjacent area. There is system release after the program ends.

4. Literal constant area-constant strings are placed here. Released by the system after the program ends

5. Program code area-stores the binary code of the function body.
The procedure is as follows:

//main.cpp int a = 0; //Global initialization area int a = 0; //Global initialization area char *p1; //Global uninitialized area main() { int b; //Stack char s [] = "abc"; //Stack char *p2; //Stack char *p3 = "123456"; //123456\0 is in the constant area and p3 is on the stack. static int c = 0; //Global (static) initialization area p1 = (char *)malloc(10); p2 = (char *)malloc(20); //The allocated areas of 10 and 20 bytes are Heap area. strcpy(p1, "123456"); //123456\0 is placed in the constant area, and the compiler may optimize it into the same place as "123456" pointed by p3. }
2.33 Programming verification in Ubuntu (x86) system and STM32 (Keil)

Coding writing:

#include <stdio.h>
#include <stdlib.h>
//Define global variables
int init_global_a = 1;
int uninit_global_a;
static int inits_global_b = 2;
static int uninits_global_b;
void output(int a)
{
printf("hello");
printf("%d",a);
printf("\
");
}

int main( )
{
//Define local variables
int a=2;//stack
static int inits_local_c=2, uninits_local_c;
    int init_local_d = 1;//stack
    output(a);
    char *p;//stack
    char str[10] = "yaoyao";//stack
    //Define constant string
    char *var1 = "1234567890";
    char *var2 = "abcdefghij";
    //Dynamic allocation - heap area
    int *p1=malloc(4);
    int *p2=malloc(4);
    //freed
    free(p1);
    free(p2);
    printf("Stack area-variable address\
");
    printf(" a:%p\
", & amp;a);
    printf("init_local_d:%p\
", & amp;init_local_d);
    printf(" p:%p\
", & amp;p);
    printf("str:%p\
", str);
    printf("\
Heap area-dynamic application address\
");
    printf(" %p\
", p1);
    printf(" %p\
", p2);
    printf("\
Global area - global variables and static variables\
");
    printf("\
.bss section\
");
    printf("Global external no initial value uninit_global_a: %p\
", & amp;uninit_global_a);
    printf("Static external no initial value uninits_global_b: %p\
", & amp;uninits_global_b);
    printf("static internal no initial value uninits_local_c: %p\
", & amp;uninits_local_c);
    printf("\
.data section\
");
    printf("There is an initial value outside the global init_global_a: %p\
", & amp;init_global_a);
    printf("Static external initial value inits_global_b: %p\
", & amp;inits_global_b);
    printf("Static internal initial value inits_local_c: %p\
", & amp;inits_local_c);
    printf("\
Literal constant area\
");
    printf("Literal constant address: %p\
",var1);
    printf("Literal constant address: %p\
",var2);
    printf("\
code area\
");
    printf("Program area address: %p\
", & amp;main);
    printf("Function address: %p\
", & amp;output);
    return 0;
}
2.33, Ubuntu running

Put the above code into the nano text editor and compile it

Compilation result: Ubuntu’s address values in the stack area and heap area grow from top to bottom.

2.34, Keil operation

Default memory configuration instructions in keil environment

① The default allocated ROM area starts at 0x8000000 and is an area with a size of 0x80000. Then this area is a read-only area and cannot be modified, that is, the code area and constant area are stored.

Modify the main function:

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"

#include <stdio.h>
#include <stdlib.h>
//Define global variables
int init_global_a = 1;
int uninit_global_a;
static int inits_global_b = 2;
static int uninits_global_b;
void output(int a)
{
printf("hello");
printf("%d",a);
printf("\
");
}

int main(void)
 {
 u16t;
u16 len;
u16 times=0;
delay_init(); //Delay function initialization
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //Set NVIC interrupt group 2: 2-bit preemption priority, 2-bit response priority
uart_init(115200); //The serial port is initialized to 115200
 LED_Init(); //LED port initialization
KEY_Init(); //Initialize the hardware interface connected to the button
 while(1)
{
//Define local variables
int a=2;
static int inits_local_c=2, uninits_local_c;
    int init_local_d = 1;
    output(a);
    char *p;
    char str[10] = "yaoyao";
    //Define constant string
    char *var1 = "1234567890";
    char *var2 = "abcdefghij";
    //Dynamic allocation
    int *p1=malloc(4);
    int *p2=malloc(4);
    //freed
    free(p1);
    free(p2);
    printf("Stack area-variable address\
");
    printf(" a:%p\
", & amp;a);
    printf("init_local_d:%p\
", & amp;init_local_d);
    printf(" p:%p\
", & amp;p);
    printf("str:%p\
", str);
    printf("\
Heap area-dynamic application address\
");
    printf(" %p\
", p1);
    printf(" %p\
", p2);
    printf("\
Global area - global variables and static variables\
");
    printf("\
.bss section\
");
    printf("Global external no initial value uninit_global_a: %p\
", & amp;uninit_global_a);
    printf("Static external no initial value uninits_global_b: %p\
", & amp;uninits_global_b);
    printf("static internal no initial value uninits_local_c: %p\
", & amp;uninits_local_c);
    printf("\
.data section\
");
    printf("There is an initial value outside the global init_global_a: %p\
", & amp;init_global_a);
    printf("Static external initial value inits_global_b: %p\
", & amp;inits_global_b);
    printf("Static internal initial value inits_local_c: %p\
", & amp;inits_local_c);
    printf("\
Literal constant area\
");
    printf("Literal constant address: %p\
",var1);
    printf("Literal constant address: %p\
",var2);
    printf("\
code area\
");
    printf("Program area address: %p\
", & amp;main);
    printf("Function address: %p\
", & amp;output);
    return 0;
}
 }

Compilation error

Reason: The declaration cannot appear after the executable state. The definition of variables in C language can only be placed at the beginning of the function and before the execution statement. This is the C89 standard.
The later C99 standard has changed, and it is OK whether it is defined before or after.

Solution: Click the magic wand, then click c/c++, check C99 mode, and then use the micro library

Compile again, success!

Burn the code into the chip

Press the reset button, the microcontroller sends data

Experimental results: The address value of the stm32 stack area decreases from top to bottom, while the heap area increases from top to bottom.

3. Result analysis (still thinking)

Generally speaking, variables within the program are allocated on the stack, the stack is from high address to low address, and the heap is from low address to high address.

Under Ubuntu, the address storage in the stack area grows upward, and the address storage in the heap area also grows upward;
Under STM32, the address storage in the stack area grows downward, but the address storage in the heap area grows upward.

Reference: [1] [Gcc related operating principles and the use of opencv under Linux system_Does opencv need to install gcc_Spicy Chicken Flavored Orange’s Blog-CSDN Blog](https://blog.csdn.net/qq_52548731/article/details /126950628?ops_request_misc= & amp;request_id= & amp;biz_id=102 & amp;utm_term=1. Learn and master the compilation and assembly process of executable programs. The learning tasks are as follows: & amp;utm_medium=distribute.pc_search_result.none- task-blog-2blogsobaiduweb~default-0-126950628.nonecase &spm=1018.2226.3001.4450)

For allocation, the stack goes from high address to low address, and the heap goes from low address to high address.

Under Ubuntu, the address storage in the stack area grows upward, and the address storage in the heap area also grows upward;
Under STM32, the address storage in the stack area grows downward, but the address storage in the heap area grows upward.

4. Summary

The general conclusion of the stack is as follows:
1. Heap and stack space allocation: stack expands to lower addresses; heap expands to higher addresses
2. If variables are defined in sequence, the memory address of the stack variable defined first is larger than the memory address of the stack variable defined later; the memory address of the heap variable defined first is smaller than the memory address of the heap variable defined later.
3. Stack temporary variables will be automatically released when exiting the scope; heap malloc variables will be released through the free function.

5. References

? [Embedded 18] Program memory allocation issues (stack, local global variables, etc.) under Ubuntu and stm32_Ubuntu software uses memory locations_Puffy Jar’s Blog-CSDN Blog