GCC背后的故事&C程序常量变量的地址分配

本文介绍了如何在Linux下使用gcc生成静态库和动态库,包括hello.c示例、x2x和x2y函数的实现,以及GCC工具集的使用。作者还详细解释了全局变量、局部变量和内存管理在不同环境中的应用,以及Cortex-M处理器的存储器地址映射。
摘要由CSDN通过智能技术生成

一. 学习并掌握可执行程序的编译、组装过程。

(1)阅读、理解和学习材料“用gcc生成静态库和动态库.pdf”和“静态库.a与.so库文件的生成与使用.pdf”,请在Linux系统(Ubuntu)下如实仿做一遍。

1.用gcc生成静态库和动态库

1.1 编译生成例子程序hello.h、hello.c、main.c
1.2 将hello.c编译成.o的文件
在这里插入图片描述
在这里插入图片描述
1.3 由.o文件创建静态库
在这里插入图片描述
在这里插入图片描述
1.4 在程序中使用静态库
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.5 由.o文件创建动态库文件
在这里插入图片描述
在这里插入图片描述
1.6 在程序中使用动态库
在这里插入图片描述

2.静态库.a与.so库文件的生成与使用

2.1新建一个文件夹test2,在里面编译生成所需要的四个文件A1.c、A2.c、A.h、test.c。
2.2 静态库.a的生成与使用
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
使用.a库文件创建可执行程序
在这里插入图片描述
2.3 共享.so文件的生成与使用
在这里插入图片描述

(2)在第一次作业的程序代码基础进行改编,除了x2x函数之外,再扩展写一个x2y函数(功能自定),main函数代码将调用x2x和x2y ;将这3个函数分别写成单独的3个 .c文件,并用gcc分别编译为3个.o 目标文件;将x2x、x2y目标文件用 ar工具生成1个 .a 静态库文件, 然后用 gcc将 main函数的目标文件与此静态库文件进行链接,生成最终的可执行程序,记录文件的大小。

1.编写x2x、x2y、main函数
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2.使gcc编译sub1.c和sub2.c得到.o文件
在这里插入图片描述
3.使用ar命令生成静态库
在这里插入图片描述
4.在程序中使用静态库
在这里插入图片描述

(3)将x2x、x2y目标文件用 ar工具生成1个 .so 动态库文件, 然后用 gcc将 main函数的目标文件与此动态库文件进行链接,生成最终的可执行程序,记录文件的大小,并与之前做对比。

1.使用gcc命令生成动态库
在这里插入图片描述
2.在程序中使用动态
在这里插入图片描述
在这里插入图片描述

二. Gcc不是一个人在战斗。请说明gcc编译工具集中各软件的用途,了解EFF文件格式。

学习任务如下:阅读、理解和学习材料“Linux GCC常用命令.pdf”和“GCC编译器背后的故事.pdf”,如实仿做一遍。

1.GCC编译器背后的故事

1.先创建一 个工作目录 test0,然后用文本编辑器生成一个 C 语言编写的简单 Hello.c 程序为示例
2.编译过程
2.1预处理在这里插入图片描述
2.2编译
在这里插入图片描述

2.3汇编
在这里插入图片描述
2.4链接
在这里插入图片描述
3.分析ELF文件
3.1 ELF文件的段
在这里插入图片描述
3.2.反汇编ELF
在这里插入图片描述

2.Linux GCC常用命令

1.简单编译一个test.c文件

在这里插入图片描述
2.预处理
在这里插入图片描述
3.编译为汇编代码
在这里插入图片描述
4.汇编
在这里插入图片描述

5.连接
在这里插入图片描述

三. 编写一个C程序,重温全局常量、全局变量、局部变量、静态变量、堆、栈等概念,在Ubuntu(x86)系统和STM32(Keil)中分别进行编程、验证(STM32 通过串口printf 信息到上位机串口助手) 。

(1)归纳出Ubuntu、stm32下的C程序中堆、栈、全局、局部等变量的分配地址,进行对比分析;

1、全局变量

在所有函数外部定义的变量称为全局变量(Global Variable),它的作用域默认是整个程序,也就是所有的源文件,包括 .c 和 .h 文件。
在这里插入图片描述a、b、x、y 都是在函数外部定义的全局变量。C语言代码是从前往后依次执行的,由于 x、y 定义在函数 func1() 之后,所以在 func1() 内无效;而 a、b 定义在源程序的开头,所以在 func1()、func2() 和 main() 内都有效。

2、局部变量

定义在函数内部的变量称为局部变量(Local Variable),它的作用域仅限于函数内部, 离开该函数后就是无效的,再使用就会报错。例如:
在这里插入图片描述

3.栈区

由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

4.堆区

一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 。它与数据结构中的堆不同,分配方式类似于链表。

5.堆和栈的区别

stack的空间由操作系统自动分配/释放,heap上的空间手动分配/释放。
stack的空间有限,heap是很大的自由存储区。
程序在编译期和函数分配内存都是在栈上进行,且程序运行中函数调用时参数的传递也是在栈上进行。

(2)加深对ARM Cortex-M/stm32F10x的存储器地址映射的理解。下图是一个Cortex-M4的存储器地址映射示意图(与Cortex-M3/stm32F10x基本相同,只存在微小差异)
在这里插入图片描述

四.总结

这次实验让我更加熟练使用并且掌握了gcc编译工具,通过几个例子学会了用gcc生成静态库和动态库,还有静态库.a和动态库.so库文件的生成和使用。也了解到了编译工具集中各个软件的用途,虽然实验过程遇到一些问题,但都通过询问同学和上网查找资料得以解决,希望通过不断的实验提升我的动手能力。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值