$NOMOD51 ; Ax51宏彙編器控制命令,禁止預定義的8051 。 使編譯器不使能預定義的;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. 

; 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 

; 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)很多的外部頁面尋址以P2

;口為高位地址的數值,有使用外部頁面RAM的情況 
;對PPAGEENABLE設置為1 ,根據硬件連接修改PPAGE的值 。 
;------------------------------------------------- -----------------------------

; Standard SFR Symbols ---標準的SFR符號 
ACC DATA 0E0H ; 關鍵字DATA A5 1偽指令定義單片機內部數據存儲器字節地址的符號 
B DATA 0F0H 
SP DATA 81H 
DPL DATA 82H 
DPH DATA 83H

NAME ?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:

IF IDATALEN <> 0 ;條 ​​件彙編指令,有IDATA區的話,清IDATA區。 
                MOV R0,#IDATALEN – 1 ;區域為0 —— IDATALEN-1 
                
CLR A 
IDATALOOP: MOV @R0,A 
DJNZ 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時,清零代碼被跳過!

 

IF XDATALEN <> 0 ;如果有外部數據區,則把外部數據區中從XDATASTART到

; XDATASTART+ XDATALEN的區域清零 
MOV DPTR,#XDATASTART 
MOV R7,#LOW (XDATALEN) 
IF (LOW (XDATALEN)) <> 0 
MOV R6,#(HIGH (XDATALEN)) +1 ;如果低地址是零,一個

;高地址就代表256字節 
ELSE 
MOV R6,#HIGH (XDATALEN) 
ENDIF 
CLR A

XDATALOOP: MOVX @DPTR,A 
INC DPTR 
DJNZ R7,XDATALOOP 
DJNZ R6,XDATALOOP

ENDIF

IF PPAGEENABLE <> 0 ;清外部頁RAM區域 
                MOV PPAGE_SFR,#PPAGE ;給P2口賦相應的值,根據用

;戶自己的目標系統。 
ENDIF

IF PDATALEN <> 0 ;清外部頁RAM區域 
                MOV R0,#LOW (PDATASTART) 
MOV R7,#LOW (PDATALEN) 
CLR A 
PDATALOOP: MOVX @R0,A 
INC R0 
DJNZ R7,PDATALOOP 
ENDIF

IF IBPSTACK <> 0 ;使用再入堆棧的情況,用戶自己在程序中定義函數的存儲模式。 
; C51定義了三個全局變量, ?C_IBP,?C_XBP,?C_PBP來存儲再入堆棧的棧頂地址 
EXTRN DATA (?C_IBP) ;聲明本模塊使用的外部全局符號,符號的段類型限制了符號

;的使用範圍,而符號本身則代表的是一個RAM單元的地址址

MOV ?C_IBP,#LOW IBPSTACKTOP 
ENDIF

IF XBPSTACK <> 0 ;函數是Large存儲模式的時候,存儲再入堆棧的區域。 
EXTRN DATA (?C_XBP) ;

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

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

#if 0 
EXTRN CODE (?B_SWITCH0) 
CALL ?B_SWITCH0 ; init bank mechanism to code bank 0

#endif 
                LJMP ?C_START ;把執行的權力交給C主函數。 也就是;說指定函數的入口點。 改句話結束以後將跳入C的main函數開始執行。

END

 

 

文章出處 http://blog.csdn.net/phenixyf/article/details/8535330

 

創作者介紹

Chi Learning

Chi Learning 發表在 痞客邦 PIXNET 留言(0) 人氣()