keil编译后生成的M51文件解析

通过*.m51文件我们可以清楚的看到单片机存储器的使用情况,以及可以看到每个变量包括局部变量的位置。
之前碰到一个问题,同样的程序,在small模式下编译后运行没问题,但在large模式下可以编译,但是运行出错。最后查看m51文件,发现了问题,在一个对时序要求很严格的地方声明几个局部变量,这几个局部变量有的被分配到data中,有的分配到xdata,在xdata中的变量访问时间要大于data中,导致整个代码时间管控出现混乱,最后将分配到xdata的变量用data修饰后,,编译成功通过。

下面是对m51文件的解析,参考一下:
BL51 BANKED LINKER/LOCATER V6.11, INVOKED BY:
C:\KEIL\C51\BIN\BL51.EXE 1910base.obj, 1910.obj TO Keil_1910 RAMSIZE (256) STACK (?STACK (0080H))

MEMORY MODEL: SMALL WITH FLOATING POINT ARITHMETIC

INPUT MODULES INCLUDED:
  1910base.obj (PROC1910)
  1910.obj (1910)
  C:\KEIL\C51\LIB\C51FPS.LIB (?C?FPADD)
  ………………………………  ;省略类同部分
  C:\KEIL\C51\LIB\C51S.LIB (?C?LSTPDATA)

LINK MAP OF MODULE:  Keil_1910 (PROC1910)

;           存储器数据分配情况
;           类型    起始地址    长度       类型           段名
            TYPE    BASE      LENGTH    RELOCATION   SEGMENT NAME
            -----------------------------------------------------

            * * * * * * *   D A T A   M E M O R Y   * * * * * * *  ; 内部数据内存区分配情况,REG代表是常规寄存器,
            REG     0000H     0008H     ABSOLUTE     "REG BANK 0"  ; 寄存器类型,从0000H开始,0008H个字节,绝对定位,寄存器BANK0
            REG     0008H     0008H     ABSOLUTE     "REG BANK 1"  ; 寄存器类型,从0000H开始,0008H个字节,绝对定位,寄存器BANK1
            DATA    0010H     0006H     UNIT         ?DT?1910

BL51 BANKED LINKER/LOCATER V6.11                                                      12/30/2009  16:15:01  PAGE 2

            DATA    0016H     0005H     UNIT         ?DT?_WRITESLITPARAMETER?1910    ;DATA代表是DATA型数据,可访问地址范围0-128,或者在 128 .. 255 范围内的一个特殊功能寄存器(SFR),以直接寻址方式操作
            DATA    001BH     0004H     UNIT         ?DT?_READSLITPARAMETER?1910
                    001FH     0001H                  *** GAP ***                     ;代表空余,未用
            DATA    0020H     0001H     BIT_ADDR     ?BA?1910
            BIT     0021H.0   0001H.4   UNIT         ?BI?1910                        ;BIT代表可以位操作的数据,是在内部数据存储空间中 20H .. 2FH 区域中一个位的地址,或者 8051 位可寻址 SFR 的一个位地址。
            BIT     0022H.4   0000H.4   UNIT         _BIT_GROUP_
            DATA    0023H     002DH     UNIT         _DATA_GROUP_
            IDATA   0050H     001FH     UNIT         _IDATA_GROUP_                   ;IDATA是可访问地址范围 0 to 255 内的数据,以间接寻址方式操作,速度略慢于DATA型数据
            IDATA   006FH     0006H     UNIT         ?ID?1910
                    0075H     000BH                  *** GAP ***
            IDATA   0080H     0001H     UNIT         ?STACK                          ;堆栈区,8051压栈的方式是向上增长,可绝对定位

            * * * * * * *  X D A T A   M E M O R Y  * * * * * * *                    ;外部数据内存分配情况,XDATA表示数据存放在外部数据存储器上
            XDATA   0000H     0065H     UNIT         ?XD?1910                        ;XDATA是存放在外部数据存储器上的数据,可访问地址范围0-65535,速度最慢
            XDATA   0065H     000CH     UNIT         _XDATA_GROUP_

            * * * * * * *   C O D E   M E M O R Y   * * * * * * *                    ;程序存储器分配情况,CODE代表是的程序指令
            CODE    0000H     0003H     ABSOLUTE
            CODE    0003H     0005H     UNIT         ?PR?RESETWATCHDOGTIMER?1910
                    0008H     0003H                  *** GAP ***
            CODE    000BH     0003H     ABSOLUTE
            ………………………… ;省略类同部分
            CODE    000EH     0011H     UNIT         ?PR?_XWRITEPOINTER?1910
            CODE    5846H     0039H     UNIT         ?PR?_READPORT?1910
            CODE    587FH     0031H     UNIT         ?PR?_X5045_WRITE?1910
            CODE    58B0H     0030H     UNIT         ?PR?X5045_READ?1910
            CODE    58E0H     002CH     UNIT         ?PR?INITSYSTEM?1910
            CODE    590CH     002CH     UNIT         ?PR?_XOUTBYTE?1910
            CODE    5938H     0028H     UNIT         ?PR?XINBYTE?1910
            CODE    5960H     0025H     UNIT         ?PR?_XREADCHAR?1910
            CODE    5985H     0020H     UNIT         ?PR?READSERIALADDRESS?1910
            CODE    59A5H     0020H     UNIT         ?CO?1910
            CODE    59C5H     0017H     UNIT         ?PR?SETWRITESTATE?1910
            CODE    59DCH     000CH     UNIT         ?PR?GETWIPSTATE?1910
            CODE    59E8H     000CH     UNIT         ?PR?_ABS?ABS

OVERLAY MAP OF MODULE:   Keil_1910 (PROC1910)

;以下是各函数中的数据分配情况
;段名                                       位操作数据起址地址      DATA数据             IDATA数据           XDATA数据
SEGMENT                                       BIT_GROUP          DATA_GROUP          IDATA_GROUP         XDATA_GROUP
  +--> CALLED SEGMENT                      START    LENGTH     START    LENGTH     START    LENGTH     START    LENGTH
----------------------------------------------------------------------------------------------------------------------
?C_C51STARTUP                              -----    -----      -----    -----      -----    -----      -----    -----
  +--> ?PR?MAIN?1910
  +--> ?C_INITSEG

; main()函数中数据使用情况(下面是调用的函数列表)
?PR?MAIN?1910                              -----    -----      0023H    0001H      -----    -----      -----    -----
  +--> ?PR?INITSYS?1910
  +--> ?PR?SENDBACKACCUMULATEERROR?1910
  +--> ?PR?INSTRECEIVEOK?1910
  +--> ?PR?EXECUTEINSTRUCTION?1910
  +--> ?PR?RESETWATCHDOGTIMER?1910
…………………………………;省略类同部分

;以下是变量、常量和寄存器等的存储位置分配

SYMBOL TABLE OF MODULE:  Keil_1910 (PROC1910)

;地址            类型          名称
  VALUE           TYPE          NAME
  ----------------------------------
  -------         MODULE        PROC1910
  C:55B0H         SEGMENT       ASMFUNCTIONS              ;C:55B0H--C代表是在Code区,即存在程序存储器(ROM)上,55B0H是地址
  C:55C1H         PUBLIC        DETERMINEBAUDRATE
  ……………………………………;省略类同部分
  D:00A8H         SYMBOL        IE                        ;D代表DATA型数据,存在RAM上0-127之间,或者在 128 .. 255 范围内的一个特殊功能寄存器(SFR),
  ……………………………………;类同部分省略
  N:0000H         SYMBOL        PROC1910
  ……………………………………;
  B:0088H.4       SYMBOL        TR0                       ;B代表可以位寻址的数据或寄存器
  B:0088H.6       SYMBOL        TR1
  ……………………………………;
  C:0000H         SYMBOL        _ICE_DUMMY_
  X:0000H         PUBLIC        LampMotorCurrentPhase     ;X代表存放在外部存储器XRAM区的数据
  C:4E55H         PUBLIC        SendBack
  …………………………………;
  C:0026H         PUBLIC        ExecuteInstruction        ;C代表村放在CODE驱动的数据或指令
  D:00B0H         PUBLIC        P3
  C:4ADEH         PUBLIC        _ReadAD
  C:568AH         PUBLIC        InstReceiveOK
  ……………………………………;
  I:0071H         PUBLIC        ScanEndWaveLength         ;I 代表可以IDATA型数据
  …………………………………
  C:41E9H         PUBLIC        _CheckLampEnergy
  X:0049H         PUBLIC        FilterMotorCurrentPhase
  ……………………………………;省略

;以下是编译结果
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
    SEGMENT: ?PR?_WRITESLITPARAMETER?1910

*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
    SEGMENT: ?PR?ASSIGNSLITPARAMETER?1910

Program Size: data=117.0 xdata=113 code=23021
LINK/LOCATE RUN COMPLETE.  2 WARNING(S),  0 ERROR(S)

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-19 15:13:24

keil编译后生成的M51文件解析的相关文章

c#:Reflector+Reflexil 修改编译后的dll/exe文件

原文:c#:Reflector+Reflexil 修改编译后的dll/exe文件 不知道大家有没有这样的经历:现场实施时测试出一个bug,明明知道某个dll/exe文件只要修改一二行代码即可,但手头没有开发环境,紧急情况下,可以用reflector + reflexil 临时直接修改dll代码,然后重编译,替换原来的文件(当然:代码未混淆的情况下,这个也可以用来搞破解,这不在本文讨论之列) 步骤: 1.Relector 加载相关的dll后,启用Reflexil界面 2.找到需要修改的代码位置,然

ant的高级使用,ant命令详解,ant打包,ant编译后打包去掉jar文件

在日常的项目开发中,我们可以经常性的需要打包测试,尤其是开发环境是windows,而实际环境则是linux. 这样的话,很多程序员要一会打一个包,一会打一个包,这些包可能会很大,实际上只有代码部分会变动,而jar包基本则不动. 当然很多人可能会说,自动化测试.很好的,我们今天要做的就是自动化测试的第一步. 这个时候我是可以使用ant来打包,去掉项目中的所有的jar文件.然后在项目的tomcat启动时到特定的地点去加载jar文件. 这样做,war包可能会只有几M,什么更小.具体如何动态的加载jar

vc++ 6.0编译后生成的文件

程序在编译后,在目标路径下会生成多个文件 Debug文件夹(*.exe,*.ilk,*.obj,*.pch,*.pdb,*.idb,*,pdb),*.cpp,*.dsp,*.ncb,*.plg       *.exe:是生成的可执行文件    *.ilk:当选定渐增型编译连接时,连接器自动生成ILK文件,记录连接信息    *.obj:是目标文件,源程序编译后的产物    *.pch:全称是PreCompiled  Header,就是预先编译好的头文件,在编译时指定/Yu开关时编译器自动生成  

Keil编译后的Code,RO,RW,ZI分别表示什么以及和芯片Flash、SRAM的对应关系

在使用keil开发STM32应用程序时,点击Build后在Build Output窗口中经常会有如下信息: <ignore_js_op> 以前一直好奇这几个参数和实际使用的STM32芯片中Flash和SRAM的对应关系,于是上网搜了一圈,做如下总结: 这些参数的单位是Byte 图中几个参数分别代表  Code:代码的大小 RO:常量所占空间 RW:程序中已经初始化的变量所占空间 ZI:未初始化的static变量和全局变量以及堆栈所占的空间 上述参数和芯片Flash以及SRAM的对应关系是  F

keil编译后Program Size: Code=46284 RO-data=988 RW-data=580 ZI-data=1094588

Program Size: Code=46284 RO-data=988 RW-data=580 ZI-data=1094588 Code      :   程序中代码所占字节大小 RO-data :   Read-only-data  ,存储在flash中的常量大小. RW-data:   Read-write-data  ,存储在flash中初始化的变量. ZI-data   :   Zero-Init-data      ,存储在SRAM中未初始化的变量. ROM(Flash) size

VS编译后直接复制DLL库文件到其他目录下

项目目录:SourceCode\公共组件\KApiClient\ 要复制的目的目录: SourceCode\公共组件\DllLibrary\ApiClient 则在项目 KApiClient下添加如下: Set OD="$(ProjectDir)..\DllLibrary\ApiClient" attrib "%OD%\$(TargetName).*" -r -a -s -h copy $(TargetName).* "%OD%" 原文地址:ht

[转]keil编译链接过程以及ARMCC、ARMASM、FROMELF、ARMLINK、ARMAR的使用

1.keil5 MDK的编译工具 armar.exe armasm.exe armcc.exe armlink.exe fromelf.exe 以及动态链接库 armcompiler_libFNP.dll 2.各工具用法 >>>armar.exe 可以在windows下使用命令行切换到该程序所在文件夹(keil5\ARM\ARMCC\bin),执行armar.exe -h进行命令查看.若有gitbash的话直接在该文件夹下右键选择gitbash here,之后运行./armar.exe

weblogic对JSP预编译、weblogic读取JSP编译后的class文件、ant中jspc预编译JSP

我们都知道在weblogic中JSP是每次第一次访问的时候才会编译,这就造成第一次访问某个JSP的时候性能下降,有时候我们也希望JSP被编译成class然后打包在jar中实现隐藏JSP的功能,下面介绍自己几天来的研究成果.在这里weblogic采用的是weblogic12c. 前提知道JSP编译之后存放的位置在:%base%\user_projects\domains\base_domain\servers\AdminServer\tmp\_WL_user\Struts\km2umq\jsp_s

浅析Class文件反编译后的文件与源码文件大小关系

1.  编辑java文件后(有注释的情况下) 使用eclipse编译后成为.class文件后 2. 使用反编译工具编译后使用自带(Ctrl+S)的保存源码方式保存 3. 仅复制java翻译后的信息 其大小目前为149字节. 后续处理 a.      现在删除掉[第一步]源码文件中无关注释行,其大小变为118字节,但是其功能仍能实现. b.      现在将[第二步]中反编译工具保存的源码删除了无关部分,再看其大小.发现只有通过删除无关代码和空行后,才能使得其大小与第三步得到为java文件大小一致