$NOMOD51       ;Ax51宏汇编器控制命令:禁止预定义的8051
;------------------------------------------------------------------------------
; 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.
; STARTUP.A51: STARTUP.A51文件所生成的代码将在单片机复位后被执行!
; To translate this file use A51 with the following invocation:
;   将按照下面的命令行语句调用A51编译器进行编译产生目标文件
;     A51 STARTUP.A51
;
; To link the modified STARTUP.OBJ file to your application use the following
; BL51 invocation:
;   将按照下面的命令行语句调用BL51连接器把STARTUP.OBJ定位连接到您的程序代码中
;     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:
; 使用下列EQU伪指令定义初始化的存储区域 在单片机复位后定义生效

;                   ; the absolute start-address of IDATA memory is always 0
IDATALEN            EQU     80H     ; the length of IDATA memory in bytes.
; IDATA(间接寻址区)其起始地址固定为0;IDATALEN用于指定需要初始化的IDATA区长度(以字节为单位)*

XDATASTART      EQU     0H      ; the absolute start-address of XDATA memory
XDATALEN           EQU      0H      ; the length of XDATA memory in bytes.
;XDATA (外部直接寻址区) XDATASTART用于指定需要初始化的XDATA区起始地址
;XDATALEN 用于指定需要初始化的XDATA区长度(以字节为单位)*

PDATASTART      EQU     0H      ; the absolute start-address of PDATA memory
PDATALEN           EQU     0H      ; the length of PDATA memory in bytes.
;PDATA(页寻址区) PDATASTART用于指定需要初始化的PDATA区起始地址
;PDATALEN用于指定需要初始化的;PDATA区长度(以字节为单位)*

; 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.

;注释:8051中 IDATA 区物理上已经包括了DATA区(直接寻址区)以及 BIT区(位寻址
             区)。C51(库)占用了 最小化内存空间,运行时程序需要把它设为0

;------------------------------------------------------------------------------
;
; Reentrant Stack Initilization
; 重入堆栈初始化

; The following EQU statements define the stack pointer for reentrant
; functions and initialized it:
; 下面的EQU语句定义重入函数的堆栈指针并初始化它

; Stack Space for reentrant functions in the SMALL model.
; SMALL模式下的重入函数的堆栈空间

IBPSTACK        EQU     0       ; set to 1 if small reentrant is used.
;如果再SMALL模式下使用重入则设为1
IBPSTACKTOP     EQU     0FFH+1 ; set top of stack to highest location+1.
;设置堆栈顶最高位置+1
;
; Stack Space for reentrant functions in the LARGE model.
; LARGE模式下的重入函数的堆栈空间
XBPSTACK        EQU     0       ; set to 1 if large reentrant is used.
;如果再LARGE模式下使用重入则设为1
XBPSTACKTOP     EQU     0FFFFH+1; set top of stack to highest location+1.
;设置堆栈顶最高位置+1
;
; Stack Space for reentrant functions in the COMPACT model.    
; COMPACT模式下的重入函数的堆栈空间
PBPSTACK        EQU     0       ; set to 1 if compact reentrant is used.
;如果再COMPACT模式下使用重入则设为1
PBPSTACKTOP     EQU     0FFFFH+1; set top of stack to highest location+1.
;设置堆栈顶最高位置+1
;
;------------------------------------------------------------------------------
;
; Page Definition for Using the Compact Model with 64 KByte xdata RAM
; 使用COMPACT模式时为64KB的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.
; 下面的EQU语句定义PDATA变量的使用了XDATA页

PPAGEENABLE     EQU     0       ; set to 1 if pdata object are used.
;如果使用PDATA页则设为1
;
PPAGE           EQU     0       ; define PPAGE number.
;定义页号
;
PPAGE_SFR       DATA    0A0H    ; SFR that supplies uppermost address byte
;SFR的最高地址字节
; (most 8051 variants use P2 as uppermost address byte)
; (大多数8051变量要用P2的最高地址字节)

;------------------------------------------------------------------------------

; Standard SFR Symbols 
; 标准SFR符号
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
;在code段的0地址处放以下代码(使用AT指令进行绝对地址的定位)
?C_STARTUP:     LJMP    STARTUP1

RSEG    ?C_C51STARTUP

STARTUP1:

IF IDATALEN <> 0   
;如果长度大于1则初始化IDATA
                MOV     R0,#IDATALEN - 1
                CLR     A
IDATALOOP:      MOV     @R0,A
                DJNZ    R0,IDATALOOP
ENDIF

IF XDATALEN <> 0  
;如果长度大于1则初始化XDATA
                MOV     DPTR,#XDATASTART
                MOV     R7,#LOW (XDATALEN)

IF (LOW (XDATALEN)) <> 0
;预置初始化时的外循环次数到R6
                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  
;如果长度大于1则初始化PDATA
                MOV     R0,#LOW (PDATASTART)
                MOV     R7,#LOW (PDATALEN)
                CLR     A
PDATALOOP:      MOVX    @R0,A
                INC     R0
                DJNZ    R7,PDATALOOP
ENDIF

IF IBPSTACK <> 0   
;SMALL模式下使用重入函数时要设置的堆栈
EXTRN DATA (?C_IBP)

MOV     ?C_IBP,#LOW IBPSTACKTOP
ENDIF

IF XBPSTACK <> 0   
;COMPACT模式下使用重入函数时要设置的堆栈
EXTRN DATA (?C_XBP)

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

IF PBPSTACK <> 0  
;LARGE模式下使用重入函数时要设置的堆栈
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
; 如果你的程序使用了Mode 4 程序分组技术(BANKING)请启用下面的程序代码
; EXTRN CODE (?B_SWITCH0)
;               CALL    ?B_SWITCH0      ; init bank mechanism to code bank 0
;程序从第一个块(bank0)开始执行
                LJMP    ?C_START ;从这里跳到你的程序入口

END

;*******************************************************************

原来的工程中没有加入startup.A51文件,程序有时会出现乱码和指针溢出的情况导致系统异常。加入此文件后,针对C8051F340单片机4K Xdata,我采样如下设置:

;
; Stack Space for reentrant functions in the LARGE model.
; LARGE模式下的重入函数的堆栈空间
XBPSTACK        EQU     1       ; set to 1 if large reentrant is used.
;如果再LARGE模式下使用重入则设为1
XBPSTACKTOP     EQU    0FFFH+1; set top of stack to highest location+1.
;设置堆栈顶最高位置+1

系统已可以稳定运行!

STARTUP.A51详解及如何使能可重入函数的更多相关文章

  1. STARTUP.A51详解

    STARTUP.A51 这个文件有什么用,有必要添加到工程吗? 如果不添加"startup.a51"文件,编译器就会自动加入一段初始化内存以及堆栈等的代码,这时的内存初始化部分你就 ...

  2. JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解

    二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 ...

  3. 详解C++中的多态和虚函数

    一.将子类赋值给父类 在C++中经常会出现数据类型的转换,比如 int-float等,这种转换的前提是编译器知道如何对数据进行取舍.类其实也是一种数据类型,也可以发生数据转换,但是这种转换只有在 子类 ...

  4. asp.netcore 3.1 program、Startup 类详解

    Program类 public class Program { /// <summary> /// 应用程序入口 /// 1.asp.netcore 本质上是控制台程序 /// </ ...

  5. 详解C语言的htons和htonl函数、大尾端、小尾端

    在Linux和Windows网络编程时需要用到htons和htonl函数,用来将主机字节顺序转换为网络字节顺序. 在Intel机器下,执行以下程序 int main(){   printf(" ...

  6. 详解C#委托,事件与回调函数

    .Net编程中最经常用的元素,事件必然是其中之一.无论在ASP.NET还是WINFrom开发中,窗体加载(Load),绘制(Paint),初始化(Init)等等.“protected void Pag ...

  7. Callback函数详解(我感觉,回掉函数的本质是函数指针,在业务做循环处理的时候,调用一下通知外部)

    2010年的最后一天了,转载一篇自己认为还不错的文章与大家分享.希望对大家有所帮助. 一,回调函数 我们经常在C++设计时通过使用回调函数可以使有些应用(如定时器事件回调处理.用回调函数记录某操作进度 ...

  8. OpenGL ES 详解纹理生成和纹理映射步骤以及函数

    通常一个纹理映射的步骤是: 创建纹理对象.就是获得一个新的纹理句柄 ID. 指定纹理.就是将数据赋值给 ID 的纹理对象,在这一步,图像数据正式加载到了 ID 的纹理对象中. 设定过滤器.定义了ope ...

  9. 详解:idea工具下的main函数只执行Thread.activeCount(),打印值为:2

    写多线程的时候,想要等main中其他线程都执行完成后(其他线程功能为对一个数字inc+1),输出最终的inc值. 于是写了个循环: while (Thread.activeCount() > 1 ...

随机推荐

  1. SQLServer Alter 修改表的列名的解决

    解决:在SQLServer中修改表的列名,可以调用存储过程sp_rename. [sql]use Test;--使用数据库  sp_rename 'd_s_t.avg_grade','avg_g',' ...

  2. linux系统下mySQL数据库 备份方法和脚本

    数据库备份1.创建个备份存储目录mkdir /root/backup/2.以下内容写到dbbackup.sh #!/bin/bash cd /data/db_backup/mysqldump -uad ...

  3. JavaScript 对象属性的遍历

    ES6一共有5种方法可以遍历对象的属性. (1)for...in for...in循环遍历对象自身的和继承的可枚举属性(不含Symbol属性). (2)Object.keys(obj) Object. ...

  4. windows服务程序

    首先创建一个myService的窗体程序作为服务安装卸载控制器(管理员身份运行vs,windows服务的安装卸载需要管理员权限)   在同一个解决方案里面添加一个windows服务程序,取名myWin ...

  5. Android系统如何实现UI的自适应

    做Android应用的人都知道,要一个apk适用多个不同的手机屏幕是很容易的,就是在项目的res文件夹下面有多套相关的资源文件.程序运行的时候,Android系统会根据当前设备的信息去加载不同文件夹下 ...

  6. JAVA的RSA加密算法工具类

    须要用到一个jar http://www.bouncycastle.org/latest_releases.html 须要注意的问题 JS用同一秘钥生成的密文用java解密出来是逆序的,即js加密12 ...

  7. JSP小实例--计算器

    package cn.com.caculate; import java.math.BigDecimal; public class caculate { private String firstNu ...

  8. [ES6] Class Inherit

    In constructor, you can call parent's constuctor() method by supert(); class ShoppingCart { construc ...

  9. gcc和g++编译c或者c++文件碰到的问题

    gcc和g++都是GNU(组织)的一个编译器.        误区一:gcc只能编译c代码,g++只能编译c++代码      两者都可以,但是请注意:      1.后缀为.c的,gcc把它当作是C ...

  10. web开发小白之路

    今天就来谈谈本人从事web开发的一系列白只又白的经历,本人刚开始是从事ios开发的,由于一系列的变故现在变为了web前端开发,不过说来也奇怪,刚开始接触前端时间可以说是彻底蒙圈,各种选择器,各种适配搞 ...