最近帮同事处理了一个RAM空间分配的问题,有一个产品的代码调用某个函数之后,程序就崩溃了。注释掉该函数的调用则恢复正常,不再崩溃,通过反汇编分析,排除了空间不够以及跨页访问问题之后,怀疑是栈空间不够导致,当调用函数时,处理器要在栈中不断保存函数调用时的现场和产生的变量,如果调用太深,而栈空间比较小,就无法容纳调用的返回地址而造成栈溢出,导致程序崩溃。

以及入口地址的lds文件之后,发现栈的大小为程序所使用的data区以及bss区所剩下的空间,根据data和bss空间大小自动调整。可见应该是程序占用太多data和bss空间,导致栈空间不够。地址空间可以分为6部分组成,包括:bss区、data区、stack区、heap区、code区、const区。打开反汇编文件(.dis文件),逐一分析占用空间比较大的变量,找到占用空间达到4KByte的全局变量。

只是自己定义了一个结构体类型,如果不定义变量,编译后代码当然在代码段;如果定义了结构体变量,则这个变量放在数据段。举个例子,structaa{inta;charb;};//这里只是声明,当然编译后在代码段你定义变量时候inta;//系统预定义的整型,a在数据段structaanumber;//number算是结构体类型aa,也在数据段,只是类型不是预定义而已。
2、请教高手,linuxCGNU,.bss与.data段的区别是.bss段是不占存储空间,原...在linux下需要加载一个可执行程序到内存时会调用exec函数exec函数会读取可执行文件的头部信息其中就包括各段(codedatabss)的起始地址和结束地址因为bss时未初始化的数据段exec函数就会把bss段【起始地址结束地址】映射到一个全0的页(叫什么名字我忘记了反正linux有专门的这么一页内存4K,所以程序(不只你的程序)未初始化的数据都映射到此页),至于linux为什么要这样,其实你可以自己想想,你未初始化一个数据(好比你定义一个Inta(全局的或静态的))你以后可能不会再程序中用它(因为你编程失误)这样因为没有跟它分配内存(而只是映射了一下)所以不会浪费宝贵的内存如果以后再程序中用到此变量如果是读则是0(此映射不会变)但是如果你写此变量他就会分配一页内存存放你的bss段(thisiscallcopyonwite),并且将此页全清零好了不说了我也是菜鸟。