开启辅助访问 切换到窄版

打印 上一主题 下一主题

内存空间四.对应程序运行

[复制链接]
楼主
跳转到指定楼层
| 只看该作者 回帖奖励 |倒序浏览 |阅读模式
今天讲解,内存空间在程序实际运行过程中的表现形式。通过前面几节的讲述,我们大概知道了,程序运行空间的内存分布,此处简单复习一下:


其实大多数情况下,开发程序的我们并不关注变量声明在堆上,还是在栈上,代码段和数据段之间到底挨着不挨着,与程序员何干?

但是某些情况下,我们确实需要理会这些内容的,最具有代表性的就是嵌入式开发,何为嵌入式开发,就是代码写完烧死了芯片中,这辈子不会再改变了。那日常生活中,哪些东西会涉及到嵌入式开发呢,举一个大家平时都会接触到的例子,手机。
手机上嵌满了各种芯片,这些芯片中,绝大多数奔跑着C语言代码,这些芯片每年是数以亿计的生产消耗,比如你要导航就需要GPS芯片;要听音乐就需要DSP芯片;到打电话,就需要GSM芯片;要刷微信,就需要LCD芯片,等等等等,为什么那么多高级语言,独独C语言选为大学理工科必修科目,是有他的道理的。
话说回来,为什么嵌入式开发就需要使用C语言呢,有这么几个原因,第一:C语言速度快,因为他是执行语言,不是解释语言,直接加载二进制程序,代码就会运行,不需要虚拟机;第二:C语言稳定,C语言的封装库很少,代码基本都是程序员码出来的,就就使得他可控性高,通过严格的测试,能够保证这些代码的正确性,不像android系统,总是会感觉内存不足,为什么苹果系统那么快,那么稳,因为IOS的本质是C;第三:空间占用少,嵌入式设备因为芯片体积小,决定了他不能拥有巨大的内存,所以C语言对于堆,栈的可见性就变得很重要。
C语言不同于其他高级语言,其他高级语言,则是不停的寻找,寻找别人封装好的库,用别人的,可以看作廉价拼凑;C语言每个功能的实现,都依赖程序员一行一行的敲代码,可以看作高端定制。对于其他高级语言来说,最重要的则是知道,我要知道,我每个接口调用以后,出来的结果是什么样的,知其然,不知其所以然。对于C程序来说,最重要的是掌控,我要知道我的程序编译出来,数据段是什么样的,代码段是什么样的,要知道代码跑起来,堆是什么样的,栈是什么样。
关注C语言的历史排名,可以看出从历史上讲Cjava(高级语言代表)就深深的纠缠在一起。Java的兴起,主要依赖互联网和大数据;C的坚挺则是他在物联网芯片领域不可替代的作用。



言归正传,让我们来创建一个包含堆,栈,数据段,代码段的程序:



因为,嵌入式开发系统,基本分为两类,实时操作系统(ucos等),非实时操作系统(Linux等)。而Linux除了嵌入式开发,也广泛的应用于后台服务器的开发,Linux系统本身就是C语言编写的。所以我们选取的调试环境就是Linux,通过gdb工具,来观察程序的运行过程。

编译工具:gcc
gdb选项:-g
调试工具:gdb
执行文件:a.out
使用到的gdb命令:
set args 参数列表(为main传入参数)
b 函数名(在函数入口打断点)
r 运行程序
p 变量(打印变量值)
I proc mapping(查看进程内存映射)
n 下个语句,不进人函数
s 下个语句,进入函数
$gcc -g mem_gdb.c




分析运行中gdb log,结合程序进程空间,得出:

代码段(.text)

数据段(.data)/数据段(.bss)

堆(heap)

栈(stack)

开始

0x400000
0x600000
0x602000
0x7ffffffde000
结束

0x401000
0x602000
0x623000
0x7ffffffff000

符号名

类型

位置

所属

main

函数
0x40056d
代码段(.text)
func

函数
0x40055d
代码段(.text)
argc

参数
0x7fffffffe4fc
栈(stack)
argv

参数
0x7fffffffe4f0
栈(stack)
a

全局变量
0x601034
数据段(.data)
b

局部变量
0x7fffffffe50c
栈(stack)
p

局部指针变量
0x602010
堆(heap)

补充说明:
1tui选项:gdb分析时候,也可以追加--tui选项打开界面显示:

tui可调节不同的视图,方法在(gdb)后输入命令,具体如下:
layout src
Standard layout—source on top, command window on the bottom
layout asm
Just like the "src" layout, except it's an assembly window on top
layout split
Three windows: source on top, assembly in the middle, and command at the bottom
layout reg
Opens the register window on top of either source or assembly, whichever was opened last
tuireggeneral
Show the general registers
tui reg float
Show the floating point registers
tuiregsystem
Show the "system" registers
tui reg next
Show the next page of registers—this is important because there might be pages of registers that aren't in the "general", "float", or "system" sets
(2)寄存器显示命令:
p $pc 程序计数器,当前运行到的行(值应该在text,否则异常);
p $sp 栈指针,当前栈顶(值应该在stack段,否则异常)
i r 查看所有寄存器,pcr14

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表