标题党为了方面后续自己翻的时候看的到

以前是直接点的否,深受吴老板的棍棒教育,不用不改就是否。hhh~

2022注解:

  • 总结起来 就是初始化寄存器,然后把IDATA、XDATA的数据都清0,然后跳转到main函数

下面是看到的一段比较全的解释,感觉懵懵懂懂是看懂了。

STARTUP.A51 这个文件有什么用,有必要添加到工程吗?
  如果不添加"startup.a51"文件,编译器就会自动加入一段初始化内存以及堆栈等的代码,这时的内存初始化部分你就无法去控制了,当然这在大部分情况下没什么关系。但是如果你想你的程序在复位后,内存里面的信息依然还保存着(所说的“热复位”),那么你就需要添加该启动文件,并且去里面修改内存初始化部分,不要初始化你需要保留的部分内存。

  启动文件. 清理RAM.设置堆栈等.即执行完start.a51后跳转到.c文件的main函数。这些初始化完毕后,还会设置SP指针。对非变量区域,如堆栈区,将不会有赋值或清零动作。

  有人喜欢改startup.a51,为了满足自己一些想当然的爱好,这是不必要的,有可能错误的。比如掉电保护的时候想保存一些变量,但改startup.a51来实现是很笨的方法,实际只要利用非变量区域的特性,定义一个指针变量指向堆栈低部:0xff处就可实现。为什么还要去改? 可以这么说:任何时候都可以不需要改startup.a51,如果你明白它的特性。 

Startup code:启动代码。

在Keil中,启动代码在复位目标系统后立即被执行。启动代码主要实现以下功能:

(1)       清除内部数据存储器

(2)       清除外部数据存储器

(3)       清除外部页存储器

(4)       初始化small模式下的可重入栈和指针

(5)       初始化large模式下的可重入栈和指针

(6)       初始化compact模式下的可重入栈和指针

(7)       初始化8051硬件栈指针

(8)       传递初始化全局变量的控制命令或者在没有初始化全局变量时给main函数传递命令。

在每一个启动文件中,提供了可供用户自己修改有来控制程序执行的汇编常量。见表1

Name

Description

IDATALEN

Specifies the number of bytes of idata to clear to 0. The default is 80h because most 8051 derivatives contain at least 128 bytes of internal data memory. Use a value of 100h for the 8052 and other derivatives that have 256 bytes of internal data memory.

XDATASTART

Specifies the initial xdata address to clear to 0.

XDATALEN

Indicates the number of bytes of xdata to clear to 0. The default is 0.

PDATASTART

Specifies the initial pdata address to clear to 0.

PDATALEN

Specifies the number of bytes of pdata to clear to 0. The default is 0.

IBPSTACK

Specifies whether or not the small model reentrant stack pointer (?C_IBP) should be initialized. A value of 1 causes this pointer to be initialized. A value of 0 prevents initialization of this pointer. The default is 0.

IBPSTACKTOP

Specifies the top of the small model reentrant stack. The default is 0xFF in idata memory.
The Cx51 Compiler does not check to see if the stack area available satisfies the requirements of the application. It is your responsibility to perform such a test.

XBPSTACK

Specifies whether or not the large model reentrant stack pointer (?C_XBP) should be initialized. A value of 1 causes this pointer to be initialized. A value of 0 prevents initialization of this pointer. The default is 0.

XBPSTACKTOP

Specifies the top of the large model reentrant stack. The default is 0xFFFF in xdata memory.
The Cx51 Compiler does not check to see if the stack area available satisfies the requirements of the application. It is your responsibility to perform such a test.

PBPSTACK

Specifies whether the compact model reentrant stack pointer (?C_PBP) should be initialized. A value of 1 causes this pointer to be initialized. A value of 0 prevents initialization of this pointer. The default is 0.

PBPSTACKTOP

Specifies the top of the compact model reentrant stack. The default is 0xFF in pdata memory.
The Cx51 Compiler does not check to see if the stack area available satisfies the requirements of the application. It is your responsibility to perform such a test.

PPAGEENABLE

Enables (a value of 1) or disables (a value of 0) Port 2 initialization for pdata memory access. The default is 0. pdata addressing uses Port 2 for the upper address (or page) byte.

PPAGE

Specifies the value to write to Port 2 of the 8051 for pdata memory access. This value represents the xdata memory page to use for pdata. This is the upper 8 bits of the absolute address range to use for pdata. For example, if the pdata area begins at address 1000h (page 10h) in xdata memory, PPAGEENABLE should be set to 1, and PPAGEshould be set to 10h. You must specify the starting pdata address to use to the BL51 Linker using the PDATA directive. For example:

BL51 input modules PDATA (1050H)

Neither the BL51 Linker nor the Cx51 Compiler checks to see if the PDATA directive and the PPAGE startup constant are correctly specified. You must ensure that these parameters contain suitable values.

上面这些只是标号,如果愿意,自己可以换成其他的名字。这样写意义更直观。


$NOMOD51  ; Ax51宏汇编器控制命令,禁止预定义的8051。使编译器不使能预定义的8051符号,避免产生重复定义的错误。
;------------------------------------------------------------------------------
;  This file is part of the C51 Compiler package
;  Copyright (c) 1988-2001 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> 
; --- BL51是Keil使用的链接器(Linker),这是命令行的使用格式,一般不用,使用IDE环境,用project管理,有相应的按钮可以实现该功能.
;
;--------------------------------------------------------------------------------------------------------------------
;
;  User-defined Power-On Initialization of Memory  --- 初始化RAM单元
;
;  With the following EQU statements the initialization of memory  --- 用下面的EQU声明初始化ram单元
;  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.  
; --- 根据你选用的芯片可以适当的修改这些值 。IDATALEN 只是一个标号,EQU只是做宏一样的替换,类似于C语言中的
; --- #define uint (unsigned int) ,以上的代码使得程序以后在碰到IDATALEN时替换成80H
;
XDATASTART  EQU    0H    ; the absolute start-address of XDATA memory  --以下两项根据目标系统的外设配置和连接自己修改
XDATALEN    EQU    0H    ; 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   ;-- 再入堆栈初始化
; --- 注意:再入堆栈的方向区别于芯片自带的堆栈的生长方式,自顶向下生长的!而SP是是自底向上的。
; --- 且再入堆栈是由编译器自己管理的,一般不必去关心,只是在有再入函数的时候,根据函数的存储器模式使用相应的RAM空间做为再入堆栈。
;
;  The following EQU statements define the stack pointer for reentrant
;  functions and initialized it:
; ---  Keil C默认情况不是用堆栈来传递参数的,所以造成函数不可重入,Keil要求用户显示声明函数是否具有可重入属性,以便为C函数调用初始化栈。
;
;  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.
;
; --- 不同内存模式下的堆栈。Keil 编译器中有三种模式设置:
; --- Small:所有的变量都放在内部RAM区
; --- Compact:所有变量在默认情况下都会放在外部RAM的低256字节中(可由R0寻址)
; --- Large:所有变量都放在外部RAM中(DPTR寻址)
; --- 这是由51处理器繁多的寻址模式导致的,不同的寻址模式有不同的效率
;
;------------------------------------------------------------------------------------------------------------------------------
;
;  Page Definition for Using the Compact Model with 64 KByte xdata RAM
; --- 使用COMPACT存储器模式时64K字节XDATA存储器空间的分页定义
;
;  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存储器空间的页地址
;---  使用EQU指令定义PFAGE时必须与L51连接定位器PDATA指令的控制参数一致
;
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) 很多的外部页面寻址以P2口为高位地址的数值,有使用外部页面RAM的情况
; --- 对PPAGEENABLE 设置为1 ,根据硬件连接修改PPAGE的值。
;
;------------------------------------------------------------------------------; Standard SFR Symbols required in XBANKING.A51  ;--- 标准的SFR符号
ACC     DATA    0E0H                  ;--- 关键字DATA A51伪指令定义单片机内部数据存储器字节地址的符号
B       DATA    0F0H
SP      DATA    81H
DPL     DATA    82H
DPH     DATA    83HNAME    ?C_STARTUP      ;--- 定义当前程序模块的目标模块名?C_C51STARTUP    SEGMENT   CODE   ;-- 定义一个可再定位的段符号名和段所在的存储空间,汇编器产生的这个段符号名在BL51/L51连接定位时用 
?STACK          SEGMENT   IDATA   ;-- 定义一个IDATA段,段名?STACK ,符合C51编译器的命名规则 (SEGMENT 用于定义一个段)RSEG    ?STACK        ;-- 声明当前段是IDATA段,段中保留空间。RSEG伪指令用于选择一个事先用SEGMENT伪指令声明的普通段DS      1           ; DS是预留空间定义指令EXTRN CODE (?C_START)    ;声明本模块引用的外部全局符号,用于和C相连接在.src文件中可以看到这个符号PUBLIC    ?C_STARTUP     ;声明可被其他模块使用的全局符号,由.src文件中可以看出这个符号的作用。CSEG    AT    0       ;结束当前的IDATA段,产生一个位于CODE中新段,起始地址是0000H。代码段的起始点
?C_STARTUP:     LJMP  STARTUP1    ;C编译器编译源程序后,芯片复位之后的复位代码第一个就是执行这条语句。RSEG    ?C_C51STARTUP    ;选择段名为?C_C51STARTUP的CODE段为当前段,存储程序代码。STARTUP1:
;---  单片机上电IDATA内存清零。如果不需要上电清零IDATA,
;---  可以注销IF到IFEDN之间的话句或者修改IDTALEN的长度
IF IDATALEN <> 0            ;如果IDATALEN不等于0 条件汇编指令,有IDATA区的话,清IDATA区。MOV    R0,#IDATALEN - 1   ;区域为0——IDATALEN-1CLR    A
IDATALOOP:    MOV    @R0,ADJNZ   R0,IDATALOOP
ENDIF;(一)如果上面idatalen=80H,那么是对0~7FH清零;如果你的程序是改写成:IDATALEN EQU 0100H ;就是对0~FFH清零。
;(二)如何按你意愿加载这段程序
;一般考虑到这个往往是你的设计中要区分上电复位和程序复位。有时候当程序复位时你不希望一些内存单元被清零了,
;那么你不对startup.a51作点修改,就不行了。
;默认是自动加载这段startup.a51的。
;所以你要这样做:把lib目录下的原始startup.a51文件拷到你的项目所在目录下,再把你项目目录下的这个startup.a51加入到你的项目中
;比如改成:IDATALEN EQU 00H ; the length of IDATA memory in bytes.
;然后编译链接。这样你的程序中就不会包含对idata清零的内码了。
;为什么?上面提到的IF语句的作用呀!当定义IDATALEN=0时,清零代码被跳过!;---  单片机上电XDATA内存清零。如果不需要上电清零XDATA,
;---  可以注销IF到IFEDN之间的话句或者修改XDATALEN的长度
IF XDATALEN <> 0                ;如果有外部数据区,则把外部数据区中从XDATASTART到XDATASTART+ XDATALEN的区域清零MOV    DPTR,#XDATASTARTMOV    R7,#LOW (XDATALEN)IF (LOW (XDATALEN)) <> 0MOV    R6,#(HIGH (XDATALEN)) +1  ;如果低地址是零,一个高地址就代表256字节ELSEMOV    R6,#HIGH (XDATALEN)ENDIFCLR    A
XDATALOOP:    MOVX   @DPTR,AINC    DPTRDJNZ   R7,XDATALOOPDJNZ   R6,XDATALOOP
ENDIFIF PPAGEENABLE <> 0              ;清外部页RAM区域MOV    P2,#PPAGE           ;给P2口赋相应的值,根据用户自己的目标系统。
ENDIF;---  单片机上电XDATA内存清零。如果不需要上电清零XDATA,
;---  可以注销IF到IFEDN之间的话句或者修改XDATALEN的长度
IF PDATALEN <> 0                ;清外部页RAM区域MOV    R0,#PDATASTARTMOV    R7,#LOW (PDATALEN)CLR    A
PDATALOOP:     MOVX   @R0,AINC    R0DJNZ   R7,PDATALOOP
ENDIF;--- 设置使用SMALL存储器模式时再入函数的堆栈空间
IF IBPSTACK <> 0               ; 使用再入堆栈的情况,用户自己在程序中定义函数的存储模式。; C51定义了三个全局变量,?C_IBP,?C_XBP,?C_PBP来存储再入堆栈的栈顶地址
EXTRN DATA (?C_IBP)             ; 声明本模块使用的外部全局符号,符号的段类型限制了符号的使用范围,; 而符号本身则代表的是一个RAM单元的地址址MOV    ?C_IBP,#LOW IBPSTACKTOP
ENDIF;--- 设置使用LARGE存储器模式时再入函数的堆栈空间
IF XBPSTACK <> 0              ;函数是Large存储模式的时候,存储再入堆栈的区域。
EXTRN DATA (?C_XBP)MOV    ?C_XBP,#HIGH XBPSTACKTOPMOV    ?C_XBP+1,#LOW XBPSTACKTOP
ENDIF
;--- 设置使用COMPACT存储器模式时再入函数的堆栈空间
IF PBPSTACK <> 0              ;函数是Compact模式的时候,存储再入堆栈栈顶地址的存储单元和栈的利用空间
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                        ; 程序从第一组bank 0 块开始执行,跳转到用户程序MAIN函数LJMP   ?C_START         ; 把执行的权力交给C主函数。也就是说指定函数的入口点。改句话结束以后将跳入C的main函数开始执行。END

创建C51工程文件疑问点---startup.A51相关推荐

  1. 安装VS2019、MFC,并创建MFC工程文件,查看工程信息

    安装VS2019.MFC.创建第一个MFC文件 1.安装VS2019 vs2019已经在4月2日正式发布,vs2019和vs2017一样强大,项目兼容,不用互相删除,而且C/C++,Python,F# ...

  2. PADS学习之路09-PADS LOGIC创建原理图工程文件

    从这节开始真正的建立工程文件,设计绘制原理图了!!! 1.启动PADS LOGIC软件 由于该软件很好的使用windows的操作风格,因此和其他的windows软件启动过程基本一致,有2种方式启动,第 ...

  3. 用ccs创建一个工程文件

    1.运行ccs5.2,打开ccs工作界面. 2.右键点击菜单栏中的project,选择新建一个工程. 3.在Project栏内填写工程名字:hello.设置工程存储路径,确认没有问题后点击Finish ...

  4. 配置Tomcat和在Eclipse中创建Web工程

    配置Tomcat服务器信息: 在Tomcat的安装目录下有一个conf目录,里面存放着Tomcat服务器的配置文件,其中最为核心的配置文件是server.xml,在这个文件里我们可以配置服务器的各种参 ...

  5. IAR因版本不兼容打不开工程文件解决(Broken options、ICC8051、XLINK)

    摘要:     本文给出IAR因版本不兼容打不开IAR工作区遇到的各种问题及解决方法,包括依据提示修改版本,删除未知名称(ewp文件).若还没解决,则创建新工作区.工程,并拷贝相关文件,我想这是一种通 ...

  6. ABOV单片机空工程文件的创建-[MC96F6332D]

    一.准备工作 1.开发环境KEIL C51软件的安装,具体的安装和路径的修改可以在CSDN中搜索参考文档:<ABOV单片机开发环境搭建及仿真说明> 2.ABOV代码生成器(CodeGen8 ...

  7. 【Groovy】IntelliJ IDEA 中创建 Gradle 工程 ( Gradle 工程目录文件分析 )

    文章目录 一.IntelliJ IDEA 中创建 Gradle 工程 二.Gradle 工程目录文件分析 一.IntelliJ IDEA 中创建 Gradle 工程 在 IntelliJ IDEA 中 ...

  8. 【SeeMusic】创建 SeeMusic 工程并编辑相关内容 ( 创建工程 | 导入 MIDI 文件 | 导入音频 | 导入视频 )

    SeeMusic 系列文章目录 [SeeMusic]下载安装并注册 SeeMusic 软件 [SeeMusic]创建 SeeMusic 工程并编辑相关内容 ( 创建工程 | 导入 MIDI 文件 | ...

  9. HDFS的API调用,创建Maven工程,创建一个非Maven工程,HDFS客户端操作数据代码示例,文件方式操作和流式操作

    1. HDFS的java操作 hdfs在生产应用中主要是客户端的开发,其核心步骤是从hdfs提供的api中构造一个HDFS的访问客户端对象,然后通过该客户端对象操作(增删改查)HDFS上的文件 1.1 ...

  10. 使用Eclipse创建Web工程后未生成web.xml文件

    使用Eclipse创建Web工程后未生成web.xml文件 鼠标右击项目,按照如下操作生成web.xml项目:

最新文章

  1. 架构师必然是孤独的领袖
  2. lt li gt html,lt;ligt;...这个符号什么意思,放在中间有什么作用?
  3. ZZUOJ1196: 单调数
  4. 几个冷门字符串算法的学习笔记(最小表示法,exKMP,Lyndon Word)
  5. 关于fetch api这点事
  6. mybatis那些事~
  7. Cell Reports:CRISPR-Cas12k引导的细菌普适性靶向遗传筛选系统
  8. 2013年6月12日星期三
  9. c#获取屏幕上某坐标点的颜色
  10. 【UVA12169】不爽的裁判
  11. armbian n1 桌面_Armbian5.89桌面版安装OpenMediaVault教程
  12. 首都师范 博弈论 9 5 3 负激励机制下的博弈模型
  13. ubuntu出现qt.qpa.plugin报错
  14. 金盾高级视频加密系统使用教程与经验分享 (金盾视频加密系统跨平台版)
  15. 历史为什么丑化隋朝_历史上被严重丑化的五大名人,明明该流传千古,却变成遗臭万年!...
  16. Word2vec代码实现
  17. python自动获取某网站二次元图片下载
  18. 后台服务(Service)
  19. 华为的研发基地“欧洲小镇”
  20. 因果论 —— 模型、推理和推断(概率、图及因果模型)①

热门文章

  1. C# Winform控件包 MaterialSkin使用教程 -- 侧边栏篇
  2. Gbase与oracle数据库的区别
  3. android 5.1声道,加入5.1声道音效非常强大_三星 I699(GALAXY Trend/电信版)_手机Android频道-中关村在线...
  4. Java 基础知识 【钢镚核恒】
  5. java 爬虫 抓取 网易云音乐
  6. MVPArms实现本现数据缓存
  7. AUTOCAD2020入门学习笔记(三)
  8. 算法排序----二分排序法
  9. NFC Reader Tool 蓝牙NFC读写器使用教学
  10. IOS如何使用第三方字体