2 Keil自带的8051汇编boot源码解析注释

2)Keil自带的8051汇编boot源码解析注释

  • 本工程主要演示使用Keil创建一个R8051XC2的默认工程,使用Keil自带的Boot汇编文件,然后对这个STARTUP.A51进行注释。
  • 工程路径:本文档同级目录/01_proj_and_src/02_Keil_boot_annotation.uvproj/
  • 你可以直接双击打开 ./01_proj_and_src/02_Keil_boot_annotation.uvproj/02_Keil_boot_annotation.uvproj工程
$NOMOD51 ; Ax51宏汇编器控制命令:禁止预定义的8051
;------------------------------------------------------------------------------
; File Encoding: UTF-8
; 将狼才鲸于2022-09-29创建工程时,从Keil选择设备列表中的设备描述中拷贝过来的
; 芯片介绍:
; flexible configurable, single-clock 8051 compatible IP core with 
; 9.4 to 12.1 times more performance than legacy 80C51 
; (with Dhrystone v1.1 Benchmark on identical clock speed, 
; depending on the MDU, number of  DPTR and 
; auto inc/dec/switch implementation).
;
; Optional features: 
; 32 I/O lines, 
; three 16-bit timer/counters, 
; compare/capture unit (CCU), 
; 18 interrupts/4 priority levels or 6 interrupts/2 priority levels, 
; two serial interfaces (UARTs), 
; serial peripheral interface (SPI), 
; I2C interface, 
; secondary I2C interface, 
; 16-bit multiplication-division unit (MDU), 
; multiple DPTR with auto-increment/auto-switch support, 
; 15-bit programmable watchdog timer with configurable prescaler, 
; power management unit (PMU), 
; direct memory access (DMA) controller, 
; real time clock (RTC), 
; internally and externally generated wait states, 
; software reset, 
; program and data memory extension up to 8MB (banking). 
;
; Optionally available: On-Chip Debug Support for 
; Keil uVision Debugger.
;
; The R8051XC IP core can be implemented in FPGA and ASIC. 
;
; *** This device is configured for 8 DPTR registers ***
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
;  This file is part of the C51 Compiler package
;  Copyright (c) 1988-2005 Keil Elektronik GmbH and Keil Software, Inc.
;  Version 8.01
;
;  *** <<< Use Configuration Wizard in Context Menu >>> ***
;------------------------------------------------------------------------------
;  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
;  Lx51 invocation:
;
;     Lx51 your object file list, STARTUP.OBJ  controls
;
;------------------------------------------------------------------------------
;
;  User-defined <h> Power-On Initialization of Memory
;
;  With the following EQU statements the initialization of memory
;  at processor reset can be defined:
;
; <o> IDATALEN: IDATA memory size <0x0-0x100>
;     <i> Note: The absolute start-address of IDATA memory is always 0
;     <i>       The IDATA space overlaps physically the DATA and BIT areas.

; IDATA是8051 0x00~0x7F的128个iRAM区域
; 8051是8位CPU,数据总线8位,地址总线16位,地址范围0x0000~0xFFFF,但是地址分为0x0000~0x00FF和0x0100~0xFFFF两部分;
; 0x00~0xFF 256个地址属于iRAM,里面既有外设寄存器,也有CPU寄存器,也有通用寄存器;
; 0x0100~0xFFFF可以认为是64k 扩展RAM;
; 其中0x00~0x7F 128个是CPU通用的寄存器、可位寻址的寄存器,还有可作为堆栈区域的iRAM,这里称为iDATA;
; 另外0x80~0xFF 128个,属于SFR特殊功能寄存器,主要是外设寄存器和CPU寄存器。
IDATALEN        EQU     80H ; 只是一个宏定义,8051通用寄存器的个数,0x00~0x7F
;
; <o> XDATASTART: XDATA memory start address <0x0-0xFFFF> 
;     <i> The absolute start address of XDATA memory
XDATASTART      EQU     0   ; 64K扩展RAM的起始地址
;
; <o> XDATALEN: XDATA memory size <0x0-0xFFFF> 
;     <i> The length of XDATA memory in bytes.
XDATALEN        EQU     0   ; 64K扩展RAM的长度,最大64K,最小0
;
; <o> PDATASTART: PDATA memory start address <0x0-0xFFFF> 
;     <i> The absolute start address of PDATA memory
PDATASTART      EQU     0H  ; 外部64K扩展RAM中的低256字节起始地址,这部分地址操作比较特殊
;
; <o> PDATALEN: PDATA memory size <0x0-0xFF> 
;     <i> The length of PDATA memory in bytes.
PDATALEN        EQU     0H  ; 外部64K扩展RAM中的低256字节总长度
;
;</h>
;------------------------------------------------------------------------------
;
;<h> Reentrant Stack Initialization
;
;  The following EQU statements define the stack pointer for reentrant
;  functions and initialized it:
;
; <h> Stack Space for reentrant functions in the SMALL model.
;  <q> IBPSTACK: Enable SMALL model reentrant stack
;     <i> Stack space for reentrant functions in the SMALL model.
; 是否初始化堆栈,大概几十个字节
IBPSTACK        EQU     0       ; set to 1 if small reentrant is used.
;  <o> IBPSTACKTOP: End address of SMALL model stack <0x0-0xFF>
;     <i> Set the top of the stack to the highest location.
; 可重入堆栈(仿真栈)的最高地址,一般是0xFF,0x00~0x1F是四组R0~R7寄存器,0x20~0x2F是位寻址区域,0x30开始是堆栈的默认起始地址
IBPSTACKTOP     EQU     0xFF +1     ; default 0FFH+1  
; </h>
;
; <h> Stack Space for reentrant functions in the LARGE model.      
;  <q> XBPSTACK: Enable LARGE model reentrant stack
;     <i> Stack space for reentrant functions in the LARGE model.
XBPSTACK        EQU     0       ; set to 1 if large reentrant is used.
;  <o> XBPSTACKTOP: End address of LARGE model stack <0x0-0xFFFF>
;     <i> Set the top of the stack to the highest location.
; 扩展RAM中堆栈的栈顶在64K的位置
XBPSTACKTOP     EQU     0xFFFF +1   ; default 0FFFFH+1 
; </h>
;
; <h> Stack Space for reentrant functions in the COMPACT model.    
;  <q> PBPSTACK: Enable COMPACT model reentrant stack
;     <i> Stack space for reentrant functions in the COMPACT model.
PBPSTACK        EQU     0       ; set to 1 if compact reentrant is used.
;
;   <o> PBPSTACKTOP: End address of COMPACT model stack <0x0-0xFFFF>
;     <i> Set the top of the stack to the highest location.
; 扩展64K RAM中低256字节中作为堆栈,栈顶0xFF
PBPSTACKTOP     EQU     0xFF +1     ; default 0FFH+1  
; </h>
;</h>
;------------------------------------------------------------------------------
;
;  Memory Page for Using the Compact Model with 64 KByte xdata RAM
;  <e>Compact Model Page Definition
;
;  <i>Define the XDATA page used for PDATA variables. 
;  <i>PPAGE must conform with the PPAGE set in the linker invocation.
;
; Enable pdata memory page initalization
; 64扩展RAM需要进行分页读取256字节x256页
PPAGEENABLE     EQU     0       ; set to 1 if pdata object are used.
;
; <o> PPAGE number <0x0-0xFF> 
; <i> uppermost 256-byte address of the page used for PDATA variables.
PPAGE           EQU     0
;
; <o> SFR address which supplies uppermost address byte <0x0-0xFF> 
; <i> most 8051 variants use P2 as uppermost address byte
; 高地址字节占用P2 IO口锁存器地址0xA0,这应该是一种约定俗成的用法
PPAGE_SFR       DATA    0A0H
;
; </e>
;------------------------------------------------------------------------------

; 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 ; 声明iRAM数据段名

                ;;以下是再定位内部RAM数据段
                RSEG    ?STACK  ; 用再定位段做当前段,以下的内容都放在这个数据段中
                DS      1       ; 从当前位置预留1字节空间备用

                EXTRN CODE (?C_START)   ; 声明外部有main函数入口
                PUBLIC  ?C_STARTUP      ; 输出本地的模块名标量

                ;;以下是绝对代码段
                CSEG    AT      0   ; 绝对代码段,地址从零开始
?C_STARTUP:     LJMP    STARTUP1    ; 本程序第一行运行的代码

                ;;以下是绝对代码段
                RSEG    ?C_C51STARTUP ; 用再定位段做当前段,以下内容放在当前端

STARTUP1:

; 清0x00~0x7F区域的寄存器
IF IDATALEN <> 0 ; 如果0x00~0x7F 127个通用寄存器数量不等于0,则进行以下处理
                MOV     R0,#IDATALEN - 1 ; 将最大的地址暂存到寄存器1
                CLR     A                ; 寄存器2赋值0(清寄存器)
IDATALOOP:      MOV     @R0,A            ; 将当前地址的寄存器赋值0
                DJNZ    R0,IDATALOOP     ; R0减1不为零则跳转到IDATALOOP标号继续执行;deduct减去,add加上
ENDIF

; 清64K所有的扩展RAM
IF XDATALEN <> 0
                MOV     DPTR,#XDATASTART    ; 将外部RAM起始地址0x00赋值给寄存器0;DPTR是16位的访问扩展RAM的地址
                MOV     R7,#LOW (XDATALEN)  ; 长度低字节赋值到寄存器0
  IF (LOW (XDATALEN)) <> 0  ; 如果低字节不为0
                MOV     R6,#(HIGH (XDATALEN)) +1 ; ; 进行256字节(BANK)对齐,只要一个BANK有数据,则清整个BANK
  ELSE                      ; 如果低字节为0
                MOV     R6,#HIGH (XDATALEN) ; 长度高字节赋值到寄存器1
  ENDIF
                CLR     A
XDATALOOP:      MOVX    @DPTR,A      ; 赋值一个外部RAM地址为0;低256字节需要用MOVX @R0
                INC     DPTR         ; 外部64K RAM地址自增1
                DJNZ    R7,XDATALOOP ; 双层循环的第一层循环
                DJNZ    R6,XDATALOOP ; 双层循环的第二层循环
ENDIF

; 定义好扩展64K RAM高地址值
IF PPAGEENABLE <> 0
                MOV     PPAGE_SFR,#PPAGE
ENDIF

; 清64K外部RAM中特殊的低256字节
IF PDATALEN <> 0
                MOV     R0,#LOW (PDATASTART)    ; 给变量0赋值特殊RAM起始地址,限定256以内
                MOV     R7,#LOW (PDATALEN)      ; 给变量1赋值特殊RAM长度,限定256以内
                CLR     A
PDATALOOP:      MOVX    @R0,A           ; 地址清零;地址自增;长度未循环完则一直循环
                INC     R0
                DJNZ    R7,PDATALOOP
ENDIF

; 如果需要,则定义各栈顶地址
; 8051数据存放的位置有几类,读写的速度也不一样,和32位CPU不一样:
; data:内部256字节iRAM,idata:64k扩展RAM的低256字节部分,
; pdata:R0 R1寻址的扩展64k RAM,xdata:DPTR寻址的扩展64k RAM
; 8051中分为硬件栈和仿真栈
IF IBPSTACK <> 0
EXTRN DATA (?C_IBP) ; 
                ; 仿真栈所在的iRAM地址栈顶,比如0xFF
                MOV     ?C_IBP,#LOW IBPSTACKTOP

ENDIF

; 如果需要,定义64K扩展RAM中的栈顶
IF XBPSTACK <> 0
EXTRN DATA (?C_XBP)

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

; 如果需要,定义64K扩展RAM中的低256字节的栈顶
IF PBPSTACK <> 0
EXTRN DATA (?C_PBP) ; Keil内部函数指针,
                MOV     ?C_PBP,#LOW PBPSTACKTOP
ENDIF

                MOV     SP,#?STACK-1 ; iRAM数据段地址

; This code is required if you use L51_BANK.A51 with Banking Mode 4
;<h> Code Banking
; <q> Select Bank 0 for L51_BANK.A51 Mode 4
#if 0   
;     <i> Initialize bank mechanism to code bank 0 when using L51_BANK.A51 with Banking Mode 4.
EXTRN CODE (?B_SWITCH0) ; 初始化扩展RAM bank0
                CALL    ?B_SWITCH0      ; init bank mechanism to code bank 0
#endif
;</h>
                LJMP    ?C_START ; 跳转到main函数执行

                END     ; 汇编文件结束

myasm51,小型的51单片机汇编源码。 基于Linux环境下编写的小型的51单片机汇编器,源码开放,采用lex和yacc两个扫描和分析工具创建,代码小巧,易于研读和分析。对汇编源程序2遍扫描完成汇编,可以生成列表文件,Intel的Hex格式的文件及.bin格式的映像文件,后两种文件可以直接下载到单片机上运行。源码程序包内包含若干示例汇编源程序(.asm),proteus的格式的数字种的仿真文件,用以测试编译结果,另有编译后的dos下的可执行文件myasm51.exe,可以在windows的命令窗口下运行。另外提供一个简明的用户手册以供参考。以下为程序包的README: What is Myasm51 =============== Myasm51 is an open source mini-assembler for the Intel MCS-51 family of microcontrollers or the compatible ones, distributed under the GPL license. By scanning the source file in two pass, Myasm51 translates a symbolic code in text file (assembly language source) into a machine executable object file. During the first pass, the assembler builds a symbol table from the symbols and labels used in the source file. In the second pass, the assembler maps the source file into machine code and generates the listing file through what it receives in the first pass. Myasm51 is an absolute assembler and only generates absolute object files in the plain binary file (with .bin extension) or the Intel Hex file (with .Hex extension) which can be read by any ROM programmer to burn the object code into the ROM space of microcontrollers. How to make =========== We assume that the UNIX utilities yacc and lex have been installed in you system, and following these steps to build Myasm51 by the super user 'root' in the Linux or the UNIX cloned system. # tar zxf myasm51-gk-20151208_121306.tar.gz # cd myasm51 # make # cp myasm51 /usr/local/bin done. How to use ========== [root@rh9 myasm51]# cd examples [root@rh9 examples]# myasm51 Myasm51 Assembler. Ver 0.01 Release 1, (20151231_165818) Snallie@tom.com, Wed Sep 30 17:28:09 CST 2015 built: Dec 31 2015 - 17:04:44 Usage: myasm51 [-o] [-F] [-C] [-d] in.asm where -ob to output binary file 'in.bin' -oh to output hex file 'in.hx' (default format) -oH to output Intel Hex file 'in.Hex' -F to fill free bit with 0 or 1, (default 0) -C to t
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值