GCC编译
预处理->编译->汇编->链接
预处理:头⽂件包含、宏替换、条件编译、删除注释...
编译:主要进⾏词法、语法、语义分析等,检查⽆误后将预处理好的⽂件编译成汇编⽂件...
汇编:将汇编⽂件转换成 ⼆进制⽬标⽂件...
链接:将项⽬中的各个⼆进制⽂件+所需的库+启动代码链接成可执⾏⽂件...
内存布局
当我们运行程序时,可加载到 RAM 中。如下是一个内存布局图。

示例代码
- #include <stdio.h>
- #include <stdlib.h>
- #include "utils.h"
- /* memory layout test */
- /* #define STR(s) #s */
- static int u_s_g_var_a; /* 未初始化静态全局变量a 存放在bss段 */
- static int i_s_g_var_b = 10; /* 已初始化静态全局变量b 存在在data段 */
- static int *u_s_g_var_p;
- static int *i_s_g_val_p = &u_s_g_var_a;
- int u_g_var_c; /* 未初始化全局变量c */
- int i_g_var_d = 10; /* 已初始化全局变量d */
- const int u_g_c_var_e; /* const 修饰未初始化全局常量 */
- const int i_g_c_var_f = 10; /* const 修饰初始化全局常量 */
- void func_test(void)
- {
- printf("func\n");
- }
- int test_memory_layout(void)
- {
- int l_var_a;
- int l_var_b = 10;
- int *l_var_c = NULL;
- int *l_var_d = NULL;
- static int u_s_l_var_e;
- static int i_s_l_var_f = 10;
- const int u_l_c_var_g;
- const int i_l_c_var_h = 10;
- char *l_var_s = "Hello World";
- char l_var_arr[] = "Hello World";
- const int *l_p_a = &l_var_a; /* 常量指针 */
- int * const l_p_b = &l_var_b; /* 指针常量 */
- const int * const l_p_c = &i_l_c_var_h; /* 指向常量的常指针 */
- int *l_var_aa = (int *)alloca(sizeof(int) * 4); /* 从栈分配内存 */
- static int *i_s_l_var_p = &u_g_var_c;
- printf("-----------------------------------------------------\n");
- printf("栈区\n");
- printf("%s\t\t%p\n", STR(l_var_aa), l_var_aa);
- printf("%s\t\t\t%p\n", STR(l_var_a), &l_var_a);
- printf("%s\t\t\t%p\n", STR(l_var_b), &l_var_b);
- printf("%s\t\t%p\n", STR(&l_var_c), &l_var_c);
- printf("%s\t\t%p\n", STR(&l_var_d), &l_var_d);
- printf("%s\t\t%p\n", STR(u_l_c_var_g), &u_l_c_var_g);
- printf("%s\t\t%p\n", STR(i_l_c_var_h), &i_l_c_var_h);
- printf("%s\t\t%p\n", STR(&l_var_s), &l_var_s);
- printf("%s\t\t\t%p\n", STR(&l_p_a), &l_p_a);
- printf("%s\t\t\t%p\n", STR(&l_p_b), &l_p_b);
- printf("%s\t\t\t%p\n", STR(&l_p_c), &l_p_c);
- printf("%s\t\t%p\n", STR(l_var_arr), l_var_arr);
- l_var_c = (int *)malloc(sizeof(int) * 4);
- l_var_d = (int *)malloc(sizeof(int) * 4);
- printf("-----------------------------------------------------\n");
- printf("堆区\n");
- printf("%s\t\t\t%p\n", STR(l_var_c), l_var_c);
- printf("%s\t\t\t%p\n", STR(l_var_d), l_var_d);
- printf("-----------------------------------------------------\n");
- printf("bss区\n");
- printf("%s\t\t%p\n", STR(u_s_g_var_a), &u_s_g_var_a);
- printf("%s\t\t%p\n", STR(u_g_var_c), &u_g_var_c);
- printf("%s\t\t%p\n", STR(u_s_l_var_e), &u_s_l_var_e);
- printf("%s\t\t%p\n", STR(u_g_c_var_e), &u_g_c_var_e);
- printf("%s\t\t%p\n", STR(&i_s_l_var_p), &i_s_l_var_p);
- printf("%s\t\t%p\n", STR(&u_s_g_var_p), &u_s_g_var_p);
- printf("%s\t\t%p\n", STR(&i_s_g_val_p), &i_s_g_val_p);
- printf("-----------------------------------------------------\n");
- printf("data区\n");
- printf("%s\t\t%p\n", STR(i_s_g_var_b), &i_s_g_var_b);
- printf("%s\t\t%p\n", STR(i_g_var_d), &i_g_var_d);
- printf("%s\t\t%p\n", STR(i_s_l_var_f), &i_s_l_var_f);
- printf("-----------------------------------------------------\n");
- printf("text区\n");
- printf("常量\n");
- printf("%s\t\t%p\n", STR(i_g_c_var_f), &i_g_c_var_f);
- printf("%s\t\t\t%p\n", STR(l_var_s), l_var_s);
- printf("代码\n");
- printf("%s\t%p\n", STR(memory_layout_test), memory_layout_test);
- printf("%s\t\t%p\n", STR(func_test), func_test);
- free(l_var_c);
- l_var_c = NULL;
- free(l_var_d);
- l_var_d = NULL;
- return 0;
- }
- void main_test(void)
- {
- printf("TEST ENTRY\n");
- printf("GNU libc version: %s\n", gnu_get_libc_version());
- memory_layout_test();
- }
复制代码 运行结果:- -----------------------------------------------------
- 栈区
- l_var_aa 0xffcc5760
- l_var_a 0xffcc5784
- l_var_b 0xffcc5788
- &l_var_c 0xffcc578c
- &l_var_d 0xffcc5790
- u_l_c_var_g 0xffcc5794
- i_l_c_var_h 0xffcc5798
- &l_var_s 0xffcc579c
- &l_p_a 0xffcc57a0
- &l_p_b 0xffcc57a4
- &l_p_c 0xffcc57a8
- l_var_arr 0xffcc57b0
- -----------------------------------------------------
- 堆区
- l_var_c 0x57f895b0
- l_var_d 0x57f895d0
- -----------------------------------------------------
- bss区
- u_s_g_var_a 0x565d0050
- u_g_var_c 0x565d004c
- u_s_l_var_e 0x565d0058
- u_g_c_var_e 0x565cca08
- i_s_l_var_p 0x565d004c
- &i_s_l_var_p 0x565d001c
- &u_s_g_var_p 0x565d0054
- &i_s_g_val_p 0x565d0018
- -----------------------------------------------------
- data区
- i_s_g_var_b 0x565d000c
- i_g_var_d 0x565d0010
- i_s_l_var_f 0x565d0014
- -----------------------------------------------------
- text区
- 常量
- i_g_c_var_f 0x565cca0c
- l_var_s 0x565cca15
- 代码
- test_memory_layout 0x565c9b5e
- func_test 0x565c9b33
复制代码 参考链接:
https://en.wikipedia.org/wiki/Data_segment
https://en.wikipedia.org/wiki/Memory_segmentation
https://medium.com/@vikasv210/memory-layout-in-c-fe4dffdaeed6
https://github.com/gatieme/AderXCoding/tree/master/language/c/memory_layout
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |