解读KeilC给C51程序自动添加的代码
2010-11-21 00:03
323 查看
用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
它们是用来清空内存、初始化全局变量的,下面是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
相关文章推荐
- 为代码自动添加注释,让Java程序的阅读和开发更高效
- 自动添加VS 2008 代码文件版权信息 注释,用小程序实现更改
- exe程序添加到服务开机自动运行
- 编写高质量代码改善C#程序的157个建议——建议137:委托和事件类型应添加上级后缀
- 为程序添加版本自动更新功能(转+详细分析)
- ubuntu添加开机自动运行程序方法
- VS中为类,函数代码自动添加版权注释信息
- 用javascript判断输入数据是否货币并自动添加¥符号的代码
- [转]VC 开机自动启动程序代码
- 【转】添加ClickOnce程序的快捷方式 ,自动运行
- VC6.0打开文件以及向工程中添加文件时程序崩溃自动退出
- 使用Doxygen软件将程序代码自动生成chm格式帮助文档
- 如果公司里有上百个表要做触发器,如果手动写代码的话。很累,所以今天写了一个小程序,自动生成mysql的触发代码。
- vim创建程序文件自动添加头部注释
- 给iOS程序添加push代码
- 将自己的代码自动添加版权信息
- VC 开机自动启动程序代码
- visual studio粘贴html代码.会自行添加一些未知代码(自动格式化)
- asp.net中上传图片并生成小图片,自动添加水印的代码 .
- 在Zend Studio中为ThinkPHP添加代码自动提示功能