stm32f0 大小端_STM32 大小端序 与 堆栈及其增长方向分析

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 16:19   594   0

//保存栈增长方向

//0,向下增长;1,向上增长.

static u8 stack_dir;

//查找栈增长方向,结果保存在stack_dir里面.

void find_stack_direction(void)

{

static u8 *addr=NULL; //用于存放第一个dummy的地址。

u8 dummy; //用于获取栈地址

if(addr==NULL) //第一次进入

{

addr=&dummy; //保存dummy的地址

find_stack_direction (); //递归

}else //第二次进入

{

if(&dummy>addr)stack_dir=1; //第二次dummy的地址大于第一次dummy,那么说明栈增长方向是向上的.

else stack_dir=0; //第二次dummy的地址小于第一次dummy,那么说明栈增长方向是向下的.

}

}

这个代码不是我写的,网上抄来的,思路很巧妙,利用递归,判断两次分配给dummy的地址,来比较栈是向下生长,还是向上生长.

如果你在STM32测试这个函数,你会发现,STM32的栈,是向下生长的.事实上,一般CPU的栈增长方向,都是向下的.

2,再来说说,堆(HEAP)的问题.全局变量,静态变量,以及内存管理所用的内存,都是属于"堆"区,英文名:"HEAP"

与栈区不同,堆区,则从内存区域的起始地址,开始分配给各个全局变量和静态变量.

堆的生长方向,都是向上的.在程序里面,所有的内存分为:堆+栈. 只是他们各自的起始地址和增长方向不同,他们没有一个固定的界限,所以一旦堆栈冲突,系统就到了崩溃的时候了.

同样,我们用附件里面的例程测试:

stack_dir的地址是0X20000004,也就是STM32的内存起始端的地址.

这里本来应该是从0X2000 0000开始分配的,但是,我仿真发现0X2000 0000总是存放:0X2000 0398,这个值,貌似是MSP,但是又不变化,还请高手帮忙解释下.

其他的,全局变量,则依次递增,地址肯定大于0X20000004,比如cpu_endian的地址就是0X20000005.

这就是STM32内部堆的分配规则.

3,再说说,大小端的问题.大端模式:低位字节存在高地址上,高位字节存在低地址上

小端模式:高位字节存在高地址上,低位字节存在低地址上

STM32属于小端模式,简单的说,比如u32 temp=0X12345678;

假设temp地址在0X2000 0010.

那么在内存里面,存放就变成了:

地址 | HEX |

0X2000 0010 | 78 56 43 12 |

CPU到底是大端还是小端,可以通过如下代码测试:

//CPU大小端

//0,小端模式;1,大端模式.

static u8 cpu_endian;

//获取CPU大小端模式,结果保存在cpu_endian里面

void find_cpu_endian(void)

{

int x=1;

if(*(char*)&x==1)cpu_endian=0; //小端模式

else cpu_endian=1; //大端模式

}

以上测试,在STM32上,你会得到cpu_endian=0,也就是小端模式.

3,最后说说,STM32内存的问题. 还是以附件工程为例,在前面第一个图,程序总共占用内存:20+2348字节,这么多内存,到底是怎么得来的呢?

我们可以双击Project侧边栏的:Targt1,会弹出test.map,在这个里面,我们就可以清楚的知道这些内存到底是怎么来的了.在这个test.map最后,Image

部分有:

==============================================================================

Image component sizes

Code (inc. data) RO Data RW Data ZI Data Debug Object Name

172 10 0 4 0 995 delay.o//delay.c里面,fac_us和fac_ms,共占用4字节

112 12 0 0 0 427 led.o

72 26 304 0 2048 828 startup_stm32f10x_hd.o //启动文件,里面定义了Stack_Size为0X800,所以这里是2048.

712 52 0 0 0 2715 sys.o

348

154 0 6 0 208720 test.o//test.c里面,stack_dir和cpu_endian 以及*addr,占用6字节.

384 24 0 8 200 3050 usart.o//usart.c定义了一个串口接收数组buffer,占用200字节.

----------------------------------------------------------------------

1800 278 336 20 2248 216735 Object Totals //总共2248+20字节

0 0 32 0 0 0 (incl. Generated)

0 0 0 2 0 0 (incl. Padding)//2字节用于对其

----------------------------------------------------------------------

Code (inc. data) RO Data RW Data ZI @R?Z6Rkn(rB8r/r/VW鵅 /f(((习(((习(1%9Q/"c"Q4Gv#{VG>) AWT(#{VD(BG{VG{V(х}( AW((х}(~&{VDzsr}3v(}}((х10RcRrv(R:>[#rv(10((rv(}}K(((}rv b;#{VGbBGj(}rv b;#{VGbBGj(((:>Y AWzsr}3v(}}((Ё(}(}((Ё((} }%Р^J(}Р>"w/2[(Р^"w/2X(}%Р"w/2[j:>(}q}(q}(}}:>[#{V<(}}:>Y AW(((} ,%I Q%=8GRV( ,%I Q%=8GRV(}T9%8qq(T9%8?qq(((((Wzs n(

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP