wowu 发表于 2025-6-25 11:58

C51的堆栈问题

C51的堆栈问题是很容易被忽略的问题,至少我之前是这样.今天早上查了一下,需要注意的问题有这么几点:
1.上电后自动设置堆栈指针SP的值(SP=0x2F)

C:0x0000    02006A   LJMP   C:006A


C:0x006A    787F   MOV      R0,#0x7F
C:0x006C    E4       CLR      A
C:0x006D    F6       MOV      @R0,A
C:0x006E    D8FD   DJNZ   R0,C:006D
C:0x0070    75812F   MOV      SP(0x81),#0x2F
C:0x0073    020003   LJMP   main(C:0003)


如代码所示,上电后直接跳转到某个地址,延时一段时间后,设置SP的值,然后才进入Main函数,执行我们定义的函数.
然而,我在STC12C5A60的数据手册中却看到:单片机复位后,堆栈指针SP为07H,指向了工作寄存器组0中的R7.也就是说SP的值是可以任意指定的,只要不与其它内存重叠.


2.C51的堆栈是向上生长的,这与ARM的向下生长不同.


3.STC12C5A60手册上还写到:用户初始化程序都应对SP设置初值,一般设在80H之后.

问题来了,80H--FFH不是特殊功能寄存器区吗?这样设置会产生重叠吗?答案是,不会重叠.

原因:高128字节RAM与特殊功能寄存器区都用80H--FFH,地址空间确实重叠,但物理上却是相互独立的.使用时通过不同的寻址方式加以区别,当内存使用时只能间接寻址,而特殊功能寄存器区只能寻址.用代码表示,就应该是这样的:

间接寻址:

MOV R0,#80H

MOV R1,@R0

直接寻址:

MOV R1,80H
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/guo_ben_/article/details/10099619

jtracy3 发表于 2025-7-2 11:21

对于 ISR,尽量只置标志位,不在中断中做复杂运算。

10299823 发表于 2025-7-3 14:51

优化中断服务程序,减少局部变量的使用,避免在中断服务程序中调用其他函数。

benjaminka 发表于 2025-7-3 16:41

随着数据的入栈(push)和出栈(pop)操作,堆栈指针会发生相应的增减。

tifmill 发表于 2025-7-3 17:41

每次压栈操作时,SP会先增加再存入数据,因此堆栈空间需预留足够余地。

phoenixwhite 发表于 2025-7-4 08:49

堆栈溢出是指在堆栈区已经满了的时候还要进行新的压栈操作

qiufengsd 发表于 2025-7-4 10:34

中断服务程序(ISR)在执行时会自动保存当前单片机状态到堆栈中。如果ISR过于复杂或频繁触发,可能会消耗大量堆栈空间,甚至导致堆栈溢出。

timfordlare 发表于 2025-7-4 11:34

在支持动态内存分配的系统中,可以使用堆分配来存储较大的数据结构,以减少对堆栈的占用

beacherblack 发表于 2025-7-4 17:08

Cx51编译器会自动将片内RAM中未分配给变量的空间作为堆栈空间。

deliahouse887 发表于 2025-7-4 18:05

避免中断服务函数中调用复杂函数            

adolphcocker 发表于 2025-7-6 11:09

C51的堆栈通常设置在片内RAM中,由于片内RAM资源有限,堆栈区的范围也是有限的。

ccook11 发表于 2025-7-6 12:59

尽量避免malloc/free,改用静态数组或全局变量

earlmax 发表于 2025-7-6 15:21

在递归调用中设置明确的终止条件,避免无限递归

mickit 发表于 2025-7-7 12:21

递归调用时,每次调用都会在堆栈中保存函数的调用信息。如果递归深度过大,容易引发堆栈溢出

claretttt 发表于 2025-7-7 13:58

在函数中定义了过多的局部变量,尤其是大型数组或结构体,会占用大量堆栈空间。

暖心小太阳 发表于 2025-7-7 19:11

确实,C51的堆栈问题很容易被忽视,尤其是在刚开始学习的时候。你的分析很到位,特别是关于堆栈指针SP的设置和堆栈的生长方向。

10299823 发表于 2025-7-10 14:45

导致程序异常甚至重启            

qiufengsd 发表于 2025-7-11 11:49

通过合理规划变量存储、手动优化SP初始化、监控堆栈需求,可有效避免堆栈问题导致的程序异常。

xiaoyaodz 发表于 2025-7-12 10:27

中断服务程序尽量使用专用寄存器组,减少堆栈消耗

elsaflower 发表于 2025-7-12 13:05

根据函数嵌套层数和中断服务程序的寄存器保存需求,计算堆栈需求。
页: [1] 2
查看完整版本: C51的堆栈问题