• 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     ; 汇编文件结束
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
  • 相关阅读:
    [附源码]java毕业设计毕业设计管理系统
    550. 游戏玩法分析 IV
    Java.lang.Class类 getEnclosingMethod()方法有什么功能呢?
    基于Java+SSM+MySQL的水果商城系统
    activiti命令模式与责任链模式
    ATtiny88初体验(四):看门狗
    MySql中事务详细理解学习(事务管理、事务隔离级别、事务传播机制)
    图片大小转换(对于图片进行压缩)
    视频质量评价
    信息安全管理体系认证对企业的好处
  • 原文地址:https://blog.csdn.net/qq582880551/article/details/127594079