解读KeilC给C51程序自动添加的代码

本文详细解析了使用KeilC编写C51程序时,在main函数执行前的一系列初始化代码。这些代码负责清空内存、初始化全局变量等任务,确保程序能够正确运行。

用KeilC编写C51的程序时,在执行main函数之前,还执行了一大段的代码

它们是用来清空内存、初始化全局变量的,下面是V3.3版本生成的代码

 

; 清空内存
 MOV      R0,#0x7F
 CLR      A
Label5:
 MOV      @R0,A
 DJNZ     R0,Label5
 MOV      SP(0x81),#0x55
 LJMP     InitVar

GotoMain:
 LJMP     main(C:1358)

; 第二个字节为变量的起始地址,存入R0
InitBytes:
 CLR      A
 MOVC     A,@A+DPTR
 INC      DPTR
 MOV      R0,A

; R7=变量大小,CY=0表示内部RAM,CY=1表示外部RAM
NextByte:
 CLR      A
 MOVC     A,@A+DPTR
 INC      DPTR
 JC       Label6
 MOV      @R0,A
 SJMP     Label7
Label6:
 MOVX     @R0,A
Label7:
 INC      R0
 DJNZ     R7, NextByte
 SJMP     NextVar

; 对位变量进行初始化
InitBits:
 CLR      A
 MOVC     A,@A+DPTR
 INC      DPTR
 MOV      R0,A   ; 位地址
; 转换为XX.Y格式
; XX存在R0中,Y存在ACC中
 ANL      A,#0x07
; 为什么加0x0C?因为0x0C等于Table - AccessTable
 ADD      A,#0x0C
 XCH      A,R0
 CLR      C
 RLC      A
 SWAP     A
 ANL      A,#0x0F
 ORL      A,#0x20
 XCH      A,R0
AccessTable:
 MOVC     A,@A+PC
 JC       Label3
 CPL      A
 ANL      A,@R0
 SJMP     Label4
Label3:
 ORL      A,@R0
Label4:
 MOV      @R0,A
 DJNZ     R7,InitBits
 SJMP     NextVar

Table:
 DS 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80

; 入口地址
InitVar:
 MOV  DPTR,#12A1
NextVar:
 CLR  A
 MOV     R6,#0x01
 MOVC    A,@A+DPTR
 JZ      GotoMain
 INC      DPTR
 MOV      R7,A
 ANL      A,#0x3F
 JNB      ACC.5,C08D8
; 需要初始化的区域大于256字节
; 第一个字节的低5位,加上第二个字节,才是区域大小
 ANL      A,#0x1F
 MOV      R6,A
 CLR      A
 MOVC     A,@A+DPTR
 INC      DPTR
 JZ       Label7
 INC      R6 ; 方便后面使用DJNZ指令
Label7:   
 XCH      A,R7
 ANL      A,#0xC0
 ADD      A,ACC(0xE0)
 JZ       InitBytes  ; Bit6=0跳转
 JC       InitBits  ; Bit7=1跳转

; 初始化需要DPTR寻址的外部RAM
; R6:R7为数据长度
; 为了能使用DJNZ指令,区域大小不是256整数倍时,R6比实际值大一
; 用R2:R0保存变量所在地址
InitLargeBytes:
 CLR      A
 MOVC     A,@A+DPTR
 INC      DPTR
 MOV      R2,A ; 变量起始地址高8位
 CLR      A
 MOVC     A,@A+DPTR
 INC      DPTR
 MOV      R0,A ; 变量起始地址低8位
NextLargeByte:
 CLR      A
 MOVC     A,@A+DPTR ; 从源地址取一字节
 INC      DPTR ; 源地址加一

; DPTR和R2:R0进行了交换,ACC内容不变
 XCH      A,R0
 XCH      A,DPL(0x82)
 XCH      A,R0
 XCH      A,R2
 XCH      A,DPH(0x83)
 XCH      A,R2

 MOVX     @DPTR,A ; 向目标地址写一字节
 INC      DPTR ; 目标地址加一

; DPTR和R2:R0进行了交换
 XCH      A,R0
 XCH      A,DPL(0x82)
 XCH      A,R0
 XCH      A,R2
 XCH      A,DPH(0x83)
 XCH      A,R2

 DJNZ     R7,NextLargeByte
 DJNZ     R6,NextLargeByte
 SJMP     NextVar

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值