sdcc man阅读笔记(五)——mem文件与map文件
一、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.g1
--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