[技术问答]

51堆栈等级的大小有多大?

[复制链接]
1717|16
手机看帖
扫描二维码
随时随地手机跟帖
18576478035|  楼主 | 2018-12-8 11:00 | 显示全部楼层 |阅读模式
求助51单片机的堆栈大小的算法,如果主程序中发生多级函数调用,比如说10层函数调用,此时进入一个中断(使用同一个寄存器组),堆栈大小是多大?10*2+15=35是这样吗?如果在进入中断中被另外一个中断优先级打断,此时的堆栈大小是多大?10*2+15+15?是这样吗?如果我的堆栈只有40个字节的话要怎么避免堆栈溢出的现象?????我在中断里面加上EA=0暂时关闭全局中断是不是可以避免堆栈溢出?
18576478035|  楼主 | 2018-12-8 11:27 | 显示全部楼层
有大神知道吗?

使用特权

评论回复
18576478035|  楼主 | 2018-12-8 14:00 | 显示全部楼层
求助

使用特权

评论回复
18576478035|  楼主 | 2018-12-8 16:19 | 显示全部楼层
求助大佬

使用特权

评论回复
幸福小强| | 2018-12-8 21:47 | 显示全部楼层
看你选的单片机的启动文件,里面都写的清清楚楚。

使用特权

评论回复
幸福小强| | 2018-12-8 21:49 | 显示全部楼层
$NOMOD51
;------------------------------------------------------------------------------
;  This file is part of the C51 Compiler package
;  Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.
;------------------------------------------------------------------------------
;  STARTUP.A51:  This code is executed after processor reset.
;
;  To translate this file use A51 with the following invocation:
;
;     A51 STARTUP.A51
;
;  To link the modified STARTUP.OBJ file to your application use the following
;  BL51 invocation:
;
;     BL51 <your object file list>, STARTUP.OBJ <controls>
;
;------------------------------------------------------------------------------
;
;  User-defined Power-On Initialization of Memory
;
;  With the following EQU statements the initialization of memory
;  at processor reset can be defined:
;
;               ; the absolute start-address of IDATA memory is always 0
IDATALEN        EQU     80H     ; the length of IDATA memory in bytes.
;
XDATASTART      EQU     0H      ; the absolute start-address of XDATA memory
XDATALEN        EQU     2FFH     ; the length of XDATA memory in bytes.
;
PDATASTART      EQU     0H      ; the absolute start-address of PDATA memory
PDATALEN        EQU     0H      ; the length of PDATA memory in bytes.
;
;  Notes:  The IDATA space overlaps physically the DATA and BIT areas of the
;          8051 CPU. At minimum the memory space occupied from the C51
;          run-time routines must be set to zero.
;------------------------------------------------------------------------------
;
;  Reentrant Stack Initilization
;
;  The following EQU statements define the stack pointer for reentrant
;  functions and initialized it:
;
;  Stack Space for reentrant functions in the SMALL model.
IBPSTACK        EQU     0       ; set to 1 if small reentrant is used.
IBPSTACKTOP     EQU     0FFH+1  ; set top of stack to highest location+1.
;
;  Stack Space for reentrant functions in the LARGE model.      
XBPSTACK        EQU     0       ; set to 1 if large reentrant is used.
XBPSTACKTOP     EQU     0FFFFH+1; set top of stack to highest location+1.
;
;  Stack Space for reentrant functions in the COMPACT model.   
PBPSTACK        EQU     0       ; set to 1 if compact reentrant is used.
PBPSTACKTOP     EQU     0FFFFH+1; set top of stack to highest location+1.
;
;------------------------------------------------------------------------------
;
;  Page Definition for Using the Compact Model with 64 KByte xdata RAM
;
;  The following EQU statements define the xdata page used for pdata
;  variables. The EQU PPAGE must conform with the PPAGE control used
;  in the linker invocation.
;
PPAGEENABLE     EQU     0       ; set to 1 if pdata object are used.
;
PPAGE           EQU     0       ; define PPAGE number.
;
PPAGE_SFR       DATA    0A0H    ; SFR that supplies uppermost address byte
;               (most 8051 variants use P2 as uppermost address byte)
;
;------------------------------------------------------------------------------

; Standard SFR Symbols
ACC     DATA    0E0H
B       DATA    0F0H
SP      DATA    81H
DPL     DATA    82H
DPH     DATA    83H



                NAME    ?C_STARTUP


?C_C51STARTUP   SEGMENT   CODE
?STACK          SEGMENT   IDATA

                RSEG    ?STACK
                DS      1

                EXTRN CODE (?C_START)
                PUBLIC  ?C_STARTUP

                CSEG    AT      0
?C_STARTUP:     LJMP    STARTUP1

                RSEG    ?C_C51STARTUP

STARTUP1:
;Disable POR
        MOV 0C7H,#0AAH
        MOV 0C7H,#55H
        MOV 0FDH,#5AH
       
        MOV 0C7H,#0AAH
        MOV 0C7H,#55H
        MOV 0FDH,#0A5H

IF IDATALEN <> 0
                MOV     R0,#IDATALEN - 1
                CLR     A
IDATALOOP:      MOV     @R0,A
                DJNZ    R0,IDATALOOP
ENDIF

IF XDATALEN <> 0
                MOV     DPTR,#XDATASTART
                MOV     R7,#LOW (XDATALEN)
  IF (LOW (XDATALEN)) <> 0
                MOV     R6,#(HIGH (XDATALEN)) +1
  ELSE
                MOV     R6,#HIGH (XDATALEN)
  ENDIF
                CLR     A
XDATALOOP:      MOVX    @DPTR,A
                INC     DPTR
                DJNZ    R7,XDATALOOP
                DJNZ    R6,XDATALOOP
ENDIF

IF PPAGEENABLE <> 0
                MOV     PPAGE_SFR,#PPAGE
ENDIF

IF PDATALEN <> 0
                MOV     R0,#LOW (PDATASTART)
                MOV     R7,#LOW (PDATALEN)
                CLR     A
PDATALOOP:      MOVX    @R0,A
                INC     R0
                DJNZ    R7,PDATALOOP
ENDIF

IF IBPSTACK <> 0
EXTRN DATA (?C_IBP)

                MOV     ?C_IBP,#LOW IBPSTACKTOP
ENDIF

IF XBPSTACK <> 0
EXTRN DATA (?C_XBP)

                MOV     ?C_XBP,#HIGH XBPSTACKTOP
                MOV     ?C_XBP+1,#LOW XBPSTACKTOP
ENDIF

IF PBPSTACK <> 0
EXTRN DATA (?C_PBP)
                MOV     ?C_PBP,#LOW PBPSTACKTOP
ENDIF

                MOV     SP,#?STACK-1
; This code is required if you use L51_BANK.A51 with Banking Mode 4
; EXTRN CODE (?B_SWITCH0)
;               CALL    ?B_SWITCH0      ; init bank mechanism to code bank 0
                LJMP    ?C_START

                END

使用特权

评论回复
xinpian101| | 2018-12-8 22:35 | 显示全部楼层
不太懂这些,学C语言时候没提到过。

使用特权

评论回复
643757107| | 2018-12-8 22:40 | 显示全部楼层
51单片机的可用内存只有00H~7FH,堆栈指针设置在60H,则堆栈的大小就是60H~7FH。

使用特权

评论回复
643757107| | 2018-12-8 22:40 | 显示全部楼层
以上是网上找到的,不知道对不对,我都是用C,不懂这个堆和栈

使用特权

评论回复
antusheng| | 2018-12-8 23:08 | 显示全部楼层
对于整个256字节的内部RAM,另外一个应用是用于堆栈。这个区域通过堆栈指针(SP)来选择,SP存储
的是栈顶的地址。当CALL、JMP或中断被调用,返回的地址就存在堆栈里面。没有限制堆栈从RAM的
什么地方开始。默认情况下,在复位后堆栈指针为07H。用户可以改变该地址为任何值。SP会指向最后
使用的值。因此SP会增加,然后地址保存到堆栈中。相反的,当堆栈的内容出栈,SP会递减。

使用特权

评论回复
antusheng| | 2018-12-8 23:08 | 显示全部楼层
922515c0bde7959016.png

使用特权

评论回复
antusheng| | 2018-12-8 23:09 | 显示全部楼层
815555c0bdea006a65.png

使用特权

评论回复
antusheng| | 2018-12-8 23:09 | 显示全部楼层
699625c0bdeb547c75.png

使用特权

评论回复
antusheng| | 2018-12-8 23:10 | 显示全部楼层
624335c0bdec9dd855.png

使用特权

评论回复
antusheng| | 2018-12-8 23:11 | 显示全部楼层
:堆栈指针复位至07H, 同时堆栈内的数据可
能丢失,即便RAM内的数据未改变。
跟堆栈有关的SP你就看手册吧,都有。

使用特权

评论回复
delin17| | 2018-12-10 14:11 | 显示全部楼层
标准51的堆栈大小,应该是0xFF-全局变量的占用的最后地址。 实际占用堆栈已用多少,0xFF-SP。

怎么减少,C51中断好像可以中断使用的Rx的寄存器组,这样就可以减少中断的堆栈使用的;具体情况看具体单片机的规格书上会有明确的说明。

使用特权

评论回复
jasontu| | 2018-12-10 17:05 | 显示全部楼层
http://www.keil.com/support/docs/192.htm
KEIL官網有說明

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

55

主题

187

帖子

2

粉丝