文章目錄
  1. 1. 一、mem文件和map文件
    1. 1.1. 1.1 mem文件
    2. 1.2. 1.2 map文件
  2. 2. 二、指定分段地址
    1. 2.1. 2.1 —xram-loc
    2. 2.2. 2.2 —code-loc
    3. 2.3. 2.3 —stack-loc
    4. 2.4. 2.4 —xstack-loc
    5. 2.5. 2.5 —idata-loc

一、mem文件和map文件

sdcc提供mem文件和map文件来帮助我们分析一个项目编译完成后,它对各种存储空间的占用情况。

1.1 mem文件

mem文件主要组成是这样的:
——内部ram使用表
——外部ram和rom使用统计表

打开在前一个实验里生成的test.mem查看的结果如下

Internal RAM layout:
0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00:|0|0|0|0|0|0|0|0|a|I|S|S|S|S|S|S|
0x10:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x20:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x30:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x40:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x50:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x60:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x70:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x80:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x90:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xa0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xb0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xc0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xd0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xe0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xf0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|

0-3:Reg Banks, T:Bit regs, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack, A:Absolute

Stack starts at: 0x0a (sp set to 0x09) with 246 bytes available.

可以看到它有一个内部ram的map图,每个字节的指派都很清晰,对于外部ram和rom,也提供了一张总体统计表。

Other memory:

Name Start End Size Max
PAGED EXT. RAM 0x0000 0x0000 1 256
EXTERNAL RAM 0x0001 0x0001 1 65536
ROM/EPROM/FLASH 0x0000 0x0079 122 65536

1.2 map文件

mem文件提供的是ram和rom的总体使用统计,而map文件,则是ram和rom的详细内存使用表。

map文件的前两段是由链接器创建的符号表,然后再是ram的详细分段。

map文件的主要组成是这样的:
——符号表
——ram map
———ram segment REG_BANK_0
———ram segment DSEG
———ram segment …..
——rom map
———-start up
———-code (代码区)
———-const(常量区)
———-lib&rel列表

在ram map中,除了分段的大小,map文件还会列出所有申明在这个区域的变量名以及该变量实际是在哪个源文件里申明的,比如DSEG段:

Area Addr Size Decimal Bytes (Attributes)
DSEG 00000000 00000080 128 bytes (REL,CON)

地址表

Value Global Global Defined In Module
00000008 _data_v test

变量表

段表的顺序是REG_BANK_0(R0-R7),DSEG(data),ISEG(idata),SSEG(stack),PSEG(pdata),XSEG(xdata),都是之前有提到的存储空间。

在rom map里,一开始是一段汇编函数的地址图,关于sdcc如何初始化单片机及c语言运行环境,之后再做分析。

进入代码区,我写了一个小的实验项目,它的代码区memory map是这样的:

Area Addr Size Decimal Bytes (Attributes)
CSEG 0000006E 00000282 642. bytes (REL,CON,CODE)

code区总表

Value Global Global Defined In Module
C: 0000006E _init_timer0 debug
C: 00000075 _count_runtime_start debug
C: 00000078 _count_runtime_over debug
C: 0000008D _init_uart debug
C: 0000009F _uart_send_char debug
C: 000000AD _delay10ms debug
C: 000000AE _delay100cyc delay
C: 000000B8 _delay10000cyc delay
C: 000000CA _HC595_Send_Data display
C: 000000F5 _HC595_Set_Row display
C: 0000012C _Led_Show_Word display
C: 0000018B _Delay10ms key
C: 000001A3 _Scan_key key
C: 00000239 _Check_Password key
C: 0000027C _board_init main
C: 0000028C _Beer main
C: 000002B3 _main main
C: 000002EC __sdcc_external_startup _startup

函数表

然后是常量区的大小和常量表(略),形式同上述data分段。

mem文件会分别列出每个函数在rom中的起始地址以及他们从哪里链接而来。也会给出所有链接的rel和lib

Files Linked [ module(s) ]

build/debug.rel [ ]
build/delay.rel [ ]
build/display.rel [ ]
build/key.rel [ ]
build/main.rel [ ]

Libraries Linked [ object file ]

/usr/bin/../share/sdcc/lib/small/mcs51.lib
[ crtclear.rel ]
/usr/bin/../share/sdcc/lib/small/mcs51.lib
[ crtxinit.rel ]
/usr/bin/../share/sdcc/lib/small/mcs51.lib
[ crtxclear.rel ]
/usr/bin/../share/sdcc/lib/small/mcs51.lib
[ crtpagesfr.rel ]
/usr/bin/../share/sdcc/lib/small/mcs51.lib
[ crtstart.rel ]
/usr/bin/../share/sdcc/lib/small/libsdcc.lib
[ _startup.rel ]

二、指定分段地址

sdcc可以用一些链接选项来修改默认的ram/rom段的起始地址。

2.1 —xram-loc

默认值为0,指定外部内存使用的起始地址,链接选项可以用16进制或者10进制,e.g

1
--xram-loc 0x8000 or --xram-loc 32768

2.2 —code-loc

修改code段在rom中的起始地址,默认为0

2.3 —stack-loc

修改堆栈指针,如果要使用这个选项,要一并使用—no-pack-iram来关闭用寄存器优化变量的访问。

2.4 —xstack-loc

默认值为pdata区域之后

2.5 —idata-loc

默认值为0x80

文章目錄
  1. 1. 一、mem文件和map文件
    1. 1.1. 1.1 mem文件
    2. 1.2. 1.2 map文件
  2. 2. 二、指定分段地址
    1. 2.1. 2.1 —xram-loc
    2. 2.2. 2.2 —code-loc
    3. 2.3. 2.3 —stack-loc
    4. 2.4. 2.4 —xstack-loc
    5. 2.5. 2.5 —idata-loc