前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >day9嵌入式(2022.1.15)

day9嵌入式(2022.1.15)

作者头像
天天Lotay
发布2022-12-02 14:32:38
3370
发布2022-12-02 14:32:38
举报
文章被收录于专栏:嵌入式音视频

===================== 1.程序文件分析 ==========================

ELF:Linux系统下,可执行程序文件。(可重定位文件)

(类似于Windows中的exe)

程序文件中,需要特别关注的文件段:

备注:

  1. file 指令,查看系统中某个文件类型。

file 文件名

  1. readelf指令,列举程序文件中文件段。

readelf -S 程序名

===================== 2.进程内存布局 ==========================

浏览一下书本 《2.4 内存管理》章节

尝试找出以下问题的答案:

  1. 虚拟内存是如何分配的呢,由什么内容组成?

内核、栈、堆、数据段、代码段、不可访问区。

  1. 上面提到的特殊关注的文件段是什么东西?中文名是啥?

.init 系统初始化代码段

.text 用户代码段

.rodata 常量数据段(只读数据段)

.data 已初始化静态数据段

.bss 未初始化静态数据段

  1. 哪些段是静态不变的,哪些段是动态变化的?

不变:数据段、代码段

变化:

  1. 我们以前的代码,操作过哪些段落?

用户代码、常量区、栈。

备注:

  1. 局部变量和全局变量

函数内部定义的变量,称为局部变量,位于栈空间

函数外部定义的变量,称为全局变量,位于静态数据段

  1. 静态数据分为 .data和.bss
代码语言:javascript
复制
int g_a=100;    // .data    已初始化,则不做任何处理

char g_b;       // .bss     未初始化,这块内存会被自动清零

(栈空间中的局部变量,如果未初始化,则为乱码数据(随机值)。)

  1. 尽量不要滥用静态数据。
  2. 静态数据生命周期与进程相当,会一直占用内存。
  3. 多线程编程中,可能导致共享资源出现问题。
  4. 函数内部定义的局部变量,在函数结束后,会被自动释放。
  5. static修饰符的用法:

修饰局部变量:将该局部变量置于静态数据段。

修饰全局变量、函数:将该变量或函数链接类型由外部链接类型修改为内部链接类型

(如果全局变量、函数只在单个文件中使用,可以使用static修饰,避免出现重名冲突)

demo1_内存分布

代码语言:javascript
复制
#include<stdio.h>

// 函数外部定义的变量,称为全局变量,位于静态数据段
int g_a=100;	// .data	不做任何处理
char g_b;		// .bss		这块内存会被自动清零

// 子函数存储在.text用户代码
unsigned char func_sum(char a, float b)	// 形参位于栈空间
{
	//  168=65+3.5+100+0
	return a+b+g_a+g_b;		// 函数返回后,会将当前函数所有栈空间数据释放。(a, b)
}

// main主函数存储在.text用户代码
int main()
{
	// 函数内部定义的变量,称为局部变量,位于栈空间
	int n1=100;		// n1位于栈空间,整型常量100位于常量区(只读区)
	float n2=3.5;	// n2位于栈空间,浮点型常量3.5位于常量区
	char n3='A';	// n3位于栈空间,字符常量'A'位于常量区
	char *str = "hello";	// str位于栈空间,字符串常量"hello"位于常量区
	// str[0] = 'a';	// 尝试对常量区写入会导致出现段错误
	printf("%c\n", *str);	// 对常量区读取是允许。

	printf("%ld %ld\n", sizeof('A'), sizeof(100));

	// sum位于栈空间,跳转到用户代码中的func_sum的入口地址
	unsigned char sum = func_sum(n3, n2);
	printf("sum: %c(%d)\n", sum, sum);

	return 0;
}

demo2_static

代码语言:javascript
复制
#include<stdio.h>

// 如需使用其他文件的函数,需要添加外部声明
extern void func_2(void);

// static:静态的

// int g_a = 200;	// 未添加static,是外部链接类型
static int g_a = 200;	// 添加static,修改为内部链接类型

void func_1(void)
{
	// int a=100;	// 局部变量
	static int a=100;	// static修饰的局部变量(只能被初始化1次)
	a++;
	printf("a(%p): %d\n", &a, a);
}

int main()
{
	func_1();
	func_1();
	func_1();
	func_1();
	func_1();

	func_2();

	return 0;
}

demo3_另一个文件

代码语言:javascript
复制
#include<stdio.h>

// 如需要使用其他文件的变量,需添加外部声明
extern int g_a;

void func_2(void)
{
	printf("g_a: %d\n", g_a);
}

demo4_堆空间使用

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
// 申请堆空间
// #include <stdlib.h>
// void *malloc(size_t size);		// 申请 size 字节的堆空间
// void *calloc(size_t nmemb, size_t size);	// 申请 nmemb*size 字节的堆空间
// void *realloc(void *ptr, size_t size);	// 重新申请一块size字节堆空间
	// 释放堆空间
// void free(void *ptr);		// 但不需要使用到该块内存时,释放空间。
// 使用场景:需要使用的内存较大,需要自行决定内存释放时机。
int main()
{
	// 1M字节 = 1024K字节 = 1024*1024 字节
	// char arr1[7*1024*1024] = {0};		
// 位于栈空间,可使用指令(ulimit -a)查看,最大是8M
	// 申请10M堆空间
	// char *arr1 = malloc(10*1024*1024);
	char *arr1 = calloc(10, 1024*1024);
	// arr1[0] = 'A';
	*(arr1+0) = 'A';
	printf("%c\n", arr1[0]);
	// 释放堆空间(当程序结束时,所有内存也会被释放。)
	free(arr1);
	return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-01-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档