Startup code:启动代码。
在Keil中,启动代码在复位目标系统后立即被执行。启动代码主要实现以下功能:
(1) 清除内部数据存储器
(2) 清除外部数据存储器
(3) 清除外部页存储器
(4) 初始化small模式下的可重入栈和指针
(5) 初始化large模式下的可重入栈和指针
(6) 初始化compact模式下的可重入栈和指针
(7) 初始化8051硬件栈指针
(8) 传递初始化全局变量的控制命令或者在没有初始化全局变量时给main函数传递命令。
在每一个启动文件中,提供了可供用户自己修改有来控制程序执行的汇编常量。
$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 , STARTUP.OBJ ;; ;------------------------------------------------------------------------------ ; ; 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 ; set to 1 if small reentrant is used. ;如果再SMALL模式下使用重入则设为1 IBPSTACKTOP EQU 0FFH+ ; set top of stack to highest location+1. ;设置堆栈顶 最高位置+1 ; ; Stack Space for reentrant functions in the LARGE model. ; LARGE模式下的重入函数的堆栈空间 XBPSTACK EQU ; set to 1 if large reentrant is used. ;如果再LARGE模式下使用重入则设为1 XBPSTACKTOP EQU 0FFFFH+; set top of stack to highest location+1. ;设置堆栈顶 最高位置+1 ; ; Stack Space for reentrant functions in the COMPACT model. ; COMPACT模式下的重入函数的堆栈空间 PBPSTACK EQU ; set to 1 if compact reentrant is used. ;如果再COMPACT模式下使用重入则设为1 PBPSTACKTOP EQU 0FFFFH+; 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 ; set to 1 if pdata object are used. ;如果使用PDATA页则设为1 ; PPAGE EQU ; 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 EXTRN CODE (?C_START) ;外部代码(这个标号将代表用户程序的启始地址) PUBLIC ?C_STARTUP ;给外部使用的符号 CSEG AT ;在code段的0地址处放以下代码(使用AT指令进行绝对地址的定位) ?C_STARTUP: LJMP STARTUP1 RSEG ?C_C51STARTUP STARTUP1: IF IDATALEN <> ;如果长度大于1则初始化IDATA CLR A IDATALOOP: MOV @R0,A DJNZ R0,IDATALOOP ENDIF IF XDATALEN <> ;如果长度大于1则初始化XDATA MOV DPTR,#XDATASTART MOV R7,#LOW (XDATALEN) IF (LOW (XDATALEN)) <> ;预置初始化时的外循环次数到R6 ELSE MOV R6,#HIGH (XDATALEN) ENDIF CLR A XDATALOOP: MOVX @DPTR,A INC DPTR DJNZ R7,XDATALOOP DJNZ R6,XDATALOOP ENDIF IF PPAGEENABLE <> MOV PPAGE_SFR,#PPAGE ENDIF IF PDATALEN <> ;如果长度大于1则初始化PDATA MOV R0,#LOW (PDATASTART) MOV R7,#LOW (PDATALEN) CLR A PDATALOOP: MOVX @R0,A INC R0 DJNZ R7,PDATALOOP ENDIF IF IBPSTACK <> ;SMALL模式下使用重入函数时要设置的堆栈 EXTRN DATA (?C_IBP) MOV ?C_IBP,#LOW IBPSTACKTOP ENDIF IF XBPSTACK <> ;COMPACT模式下使用重入函数时要设置的堆栈 EXTRN DATA (?C_XBP) MOV ?C_XBP,#HIGH XBPSTACKTOP ,#LOW XBPSTACKTOP ENDIF IF PBPSTACK <> ;LARGE模式下使用重入函数时要设置的堆栈 EXTRN DATA (?C_PBP) MOV ?C_PBP,#LOW PBPSTACKTOP ENDIF ; 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