ADS的默认连接分析及编译器产生符号解惑
ADS的默认连接顺序是怎样的呢?例如下边从2440init.s中摘出的编译器符号又该怎样理解呢?
BaseOfROM DCD |Image##RO##Base|
TopOfROM DCD |Image##RO##Limit|
BaseOfBSS DCD |Image##RW##Base|
BaseOfZero DCD |Image##ZI##Base|
EndOfBSS DCD |Image##ZI##Limit|
说明:由于“$ $”(实际上中间没有空格,但是不知为什么只要这两个字符并排着放在一起,提交后显示的时候总是出现问题)排版的问题,所以本文中所有用到的“$ $”都用##代替。
我根据TQ2440_Test.mcp做了一个测试。我知道下边的图片对于使用ADS的朋友很熟悉,但是我觉得还是有必要先把这个工程的编译配置选项贴出来。
为了说明这些问题,我不得不把ADS生成的List.txt内容列出来,尽管它很长,不过只去注意那些对问题有意义的地方。
================================================================================
Memory Map of the image
Image Entry point : 0x30000000
Load Region LR_1 (Base: 0x30000000, Size: 0x00086c14, Max: 0xffffffff, ABSOLUTE)
Execution Region ER_RO (Base: 0x30000000,Size: 0x0000b400, Max: 0xffffffff, ABSOLUTE)
Base Addr Size Type Attr Idx E Section Name Object
0x30000000 0x00000544 Code RO 1 * Init 2440init.o
0x30000544 0x0000026c Code RO 10 .text nand.o
0x300007b0 0x00000aa0 Code RO 59 .text 2440lib.o
0x30001250 0x00000550 Code RO 145 .text Main.o
0x300017a0 0x00000288 Code RO 210 .text mmu.o
0x30001a28 0x0000046c Code RO 226 .text dma.o
0x30001e94 0x0000019c Code RO 264 .text Adc.o
0x30002030 0x00000e7c Code RO 279 .text camif.o
0x30002eac 0x000007f0 Code RO 411 .text IIC.o
0x3000369c 0x0000026c Code RO 445 .text keyscan.o
0x30003908 0x00000120 Code RO 501 .text RTC.o
0x30003a28 0x000003e8 Code RO 513 .text Test_OV9650.o
0x30003e10 0x0000026c Code RO 606 .text Touchpanel.o
0x3000407c 0x000005b4 Code RO 620 .text UDA1341.o
0x30004630 0x00000cdc Code RO 643 .text AudioDrv.o
0x3000530c 0x00000af0 Code RO 731 .text LCD_TFT.o
0x30005dfc 0x00001018 Code RO 766 .text SD_MMC.o
0x30006e14 0x00000034 Code RO 831 .text atoi.o(c_a__un.l)
0x30006e48 0x00000014 Code RO 833 .text rt_ctype_table.o(c_a__un.l)
0x30006e5c 0x000000d4 Code RO 835 .text rt_sdiv.o(c_a__un.l)
0x30006f30 0x000000c0 Code RO 837 .text rt_udiv.o(c_a__un.l)
0x30006ff0 0x00000068 Code RO 839 .text strlen.o(c_a__un.l)
0x30007058 0x00000058 Code RO 841 .text vsprintf.o(c_a__un.l)
0x300070b0 0x00000d38 Code RO 860 .text __vfpntf.o(c_a__un.l)
0x30007de8 0x0000001c Code RO 862 .text _sputc.o(c_a__un.l)
0x30007e04 0x0000003c Code RO 864 .text lc_ctype_c.o(c_a__un.l)
0x30007e40 0x0000000c Code RO 867 .text libspace.o(c_a__un.l)
0x30007e4c 0x0000000c Code RO 870 .text rt_div0.o(c_a__un.l)
0x30007e58 0x0000000c Code RO 872 .text rt_errno_addr.o(c_a__un.l)
0x30007e64 0x00000010 Code RO 874 .text rt_fp_status_addr.o(c_a__un.l)
0x30007e74 0x000000c0 Code RO 876 .text strtol.o(c_a__un.l)
0x30007f34 0x00000924 Code RO 894 .text _fp_disp.o(c_a__un.l)
0x30008858 0x00000060 Code RO 896 .text _fptrap.o(c_a__un.l)
0x300088b8 0x00000108 Code RO 898 .text _strtoul.o(c_a__un.l)
0x300089c0 0x00000098 Code RO 900 .text lludiv10.o(c_a__un.l)
0x30008a58 0x00000018 Code RO 902 .text rt_raise.o(c_a__un.l)
0x30008a70 0x0000002c Code RO 904 .text rtudiv10.o(c_a__un.l)
0x30008a9c 0x000000a0 Code RO 906 .text strcmp.o(c_a__un.l)
0x30008b3c 0x00000064 Code RO 910 .text __raise.o(c_a__un.l)
0x30008ba0 0x00000020 Code RO 912 .text _chval.o(c_a__un.l)
0x30008bc0 0x0000015c Code RO 914 .text bigflt0.o(c_a__un.l)
0x30008d1c 0x0000003c Code RO 919 .text lc_numeric_c.o(c_a__un.l)
0x30008d58 0x00000040 Code RO 922 .text rtsdiv10.o(c_a__un.l)
0x30008d98 0x00000018 Code RO 924 .text sys_exit.o(c_a__un.l)
0x30008db0 0x00000048 Code RO 928 .text classify.o(m_a_pu.l)
0x30008df8 0x00000054 Code RO 930 .text dtoi.o(m_a_pu.l)
0x30008e4c 0x00000160 Code RO 932 .text defsig.o(c_a__un.l)
0x30008fac 0x00000004 Code RO 936 .text use_semi.o(c_a__un.l)
0x30008fb0 0x00000018 Code RO 938 .text sys_wrch.o(c_a__un.l)
0x30008fc8 0x000001b4 Code RO 6 C$$code 2440slib.o
0x3000917c 0x00000898 Code RO 917 CL$$btodstuff btod.o(c_a__un.l)
0x30009a14 0x00000014 Code RO 446 i.ClearPending keyscan.o
0x30009a28 0x00000048 Code RO 516 i.OV9650_sccb_end Test_OV9650.o
0x30009a70 0x00000054 Code RO 515 i.OV9650_sccb_start Test_OV9650.o
0x30009ac4 0x00000050 Code RO 517 i.OV9650_sccb_write_bit Test_OV9650.o
0x30009b14 0x00000034 Code RO 518 i.OV9650_sccb_writechar Test_OV9650.o
0x30009b48 0x00000038 Code RO 644 i.SetPlayDma AudioDrv.o
0x30009b80 0x00000038 Code RO 645 i.SetRecDma AudioDrv.o
0x30009bb8 0x00000054 Code RO 514 i.set_gpio_ctrl Test_OV9650.o
0x30009c0c 0x0000049c Code RO 845 x$fpl$dadd daddsub.o(f_a_p.l)
0x3000a0a8 0x00000040 Code RO 880 x$fpl$dcheck dcheck.o(f_a_p.l)
0x3000a0e8 0x00000018 Code RO 882 x$fpl$dcheck1 dcheck1.o(f_a_p.l)
0x3000a100 0x000005b0 Code RO 847 x$fpl$ddiv ddiv.o(f_a_p.l)
0x3000a6b0 0x000000a4 Code RO 849 x$fpl$dfix dfix.o(f_a_p.l)
0x3000a754 0x00000064 Code RO 852 x$fpl$dflt dflt.o(f_a_p.l)
0x3000a7b8 0x000002b4 Code RO 854 x$fpl$dmul dmul_mull.o(f_a_p.l)
0x3000aa6c 0x00000230 Code RO 884 x$fpl$dunder dunder.o(f_a_p.l)
0x3000ac9c 0x00000164 Code RO 886 x$fpl$exception except.o(f_a_p.l)
0x3000ae00 0x0000003c Code RO 926 x$fpl$ieeestatus istatus.o(f_a_p.l)
0x3000ae3c 0x00000004 Code RO 878 x$fpl$printf1 printf1.o(f_a_p.l)
0x3000ae40 0x00000098 Code RO 908 x$fpl$retnan retnan.o(f_a_p.l)
0x3000aed8 0x000000a4 Code RO 892 x$fpl$trapveneer trapv.o(f_a_p.l)
0x3000af7c 0x000000d3 Data RO 147 .constdata Main.o
0x3000b04f 0x00000001 PAD (说明:为了使代码4字节对齐,起到占位作用,占了一个字节)
0x3000b050 0x00000058 Data RO 622 .constdata UDA1341.o
0x3000b0a8 0x00000110 Data RO 865 .constdata lc_ctype_c.o(c_a__un.l)
0x3000b1b8 0x00000094 Data RO 915 .constdata bigflt0.o(c_a__un.l)
0x3000b24c 0x0000001c Data RO 920 .constdata lc_numeric_c.o(c_a__un.l)
0x3000b268 0x0000012b Data RO 933 .constdata defsig.o(c_a__un.l)
0x3000b393 0x00000001 PAD (说明:为了使代码4字节对齐,起到占位作用,占了一个字节)
0x3000b394 0x00000040 Data RO 521 .constdata_check_OV9650 Test_OV9650.o
0x3000b3d4 0x0000002c Data RO 522 .constdata_s3c2440_camif_init Test_OV9650.oExecution Region ER_RW (Base: 0x3000b400, Size: 0x0007b814, Max: 0xffffffff, ABSOLUTE)
Base Addr Size Type Attr Idx E Section Name Object
0x3000b400 0x00000004 Data RW 60 .data 2440lib.o
0x3000b404 0x00000068 Data RW 146 .data Main.o
0x3000b46c 0x00000004 Data RW 265 .data Adc.o
0x3000b470 0x000003ec Data RW 519 .data Test_OV9650.o
0x3000b85c 0x0003b760 Data RW 621 .data UDA1341.o
0x30046fbc 0x00000058 Data RW 646 .data AudioDrv.o
0x30047014 0x0003fc00 Data RW 760 .data TQ_LOGO.oExecution Region ER_ZI (Base: 0x30086c14, Size: 0x000415b8, Max: 0xffffffff, ABSOLUTE)
Base Addr Size Type Attr Idx E Section Name Object
0x30086c14 0x00000004 Zero RW 61 .bss 2440lib.o
0x30086c18 0x00000020 Zero RW 148 .bss Main.o
0x30086c38 0x00000004 Zero RW 153 .bss Main.o
0x30086c3c 0x00000004 Zero RW 155 .bss Main.o
0x30086c40 0x00000020 Zero RW 227 .bss dma.o
0x30086c60 0x00000004 Zero RW 266 .bss Adc.o
0x30086c64 0x00000024 Zero RW 280 .bss camif.o
0x30086c88 0x00000230 Zero RW 412 .bss IIC.o
0x30086eb8 0x00001400 Zero RW 520 .bss Test_OV9650.o
0x300882b8 0x0000000c Zero RW 607 .bss Touchpanel.o
0x300882c4 0x00000004 Zero RW 623 .bss UDA1341.o
0x300882c8 0x00000064 Zero RW 647 .bss AudioDrv.o
0x3008832c 0x0003fc00 Zero RW 732 .bss LCD_TFT.o
0x300c7f2c 0x00000240 Zero RW 767 .bss SD_MMC.o
0x300c816c 0x00000060 Zero RW 868 .bss libspace.o(c_a__un.l)
================================================================================Image component sizes
Code RO Data RW Data ZI Data Debug29120 407 505876 267608 114304 Object Totals
15804 747 0 96 5096 Library Totals================================================================================
Code RO Data RW Data ZI Data Debug44924 1154 505876 267704 119400 Grand Totals
================================================================================
Total RO Size(Code + RO Data) 46078 ( 45.00kB) (0x0000B3FE)
Total RW Size(RW Data + ZI Data) 773580 ( 755.45kB) (0x000BCDCC)
Total ROM Size(Code + RO Data + RW Data) 551954 ( 539.02kB) (0x00086C12)================================================================================
分析:
(1)从Image Entry point : 0x30000000这句话中,我们可以看出程序的入口地址是0x30000000。
(2)上边橙色的部分是"RO Data"段,List.txt并没有把这一部分单列出来,而是与Code段放在一起。
(3)从Load Region LR_1 (Base: 0x30000000, Size: 0x00086c14, Max: 0xffffffff, ABSOLUTE)这句话中,我们可以知道最终下载程序(TQ2440_Test.bin)的大小是0x00086C14。如果想知道为什么是这个数,可以通过Jlink软件把TQ2440_Test.bin打开,然后看代码量就可以知道。
从Total ROM Size(Code + RO Data + RW Data) 551954 ( 539.02kB) (0x00086C12)这句,我们可以看出下载程序的代码量应该是0x00086C12,这与0x00086C14是矛盾的。其实不然,这是因为在"RO Data"段为了4字节对齐,用了两个单字节占位引起的多余空间。
(4)如果最终下载程序(TQ2440_Test.bin)的大小是0x00086C14,而并没有把bss段或者叫ZI段(0x000415b8)这部分算进去。也就是说最终的下载程序是不包括bss段的,bss段不会被下载到Flash或者RAM中,这也是为什么启动代码(比如说boot.s)要进行bss段初始化的原因。
(5)ADS默认的链接顺序就是代码段(.text)、只读数据段(.rodata)、(已初始化)数据段(.data)、未初始化数据段(.bss)。假设projiect里有三个文件,head.s、nand.c、maic.c,那么默认为的就先依次放这三个文件的代码段(head.s(.text)、nand.c(.text)、maic.c(.text)),再依次放只读数据段(head.s(.rodata)、nand.c(.rodata)、maic.c(.rodata)),依次再放这三个文件的数据段(head.s(.data)、nand.c(.data)、maic.c(.data)),最后再放(head.s(.bss)、nand.c(.bss)、maic.c(.bss))。
(6)为了理解编译器符号,我从TQ2440_Test.dis摘出的对应的反汇编代码如下。
300003b4 <BaseOfROM>:
300003b4: andcc r0, r0, r0 300003b8 <TopOfROM>:
300003b8: 3000b400 andcc fp, r0, r0, lsl # 300003bc <BaseOfBSS>:
300003bc: 3000b400 andcc fp, r0, r0, lsl # 300003c0 <BaseOfZero>:
300003c0: 30086c14 andcc r6, r8, r4, lsl ip 300003c4 <EndOfBSS>:
300003c4: 300c81cc andcc r8, ip, ip, asr #
注意把这些值与List.txt中深蓝色字体对比,你就会发现其中的奥秘。30000000、3000b400、30086c14都可以在深蓝色字体中找到,需要指出的是300c81cc这个数字。这个数字是这样理解的, 从“Execution Region ER_ZI (Base: 0x30086c14, Size: 0x000415b8, Max: 0xffffffff, ABSOLUTE)”这句话中我们可以看出,bss段(ZI段)的基址是0x30086c14,大小是 0x000415b8,把这两个数字加起来就可以得到bss段的终址是300c81cc。
由此,我们得出对ADS编译器生成的各段的认识如下所示。
BaseOfROM DCD |Image##RO##Base| 代码段的首地址
TopOfROM DCD |Image##RO##Limit| 代码段的结束地址
BaseOfBSS DCD |Image##RW##Base| 数据段的起始地址
BaseOfZero DCD |Image##ZI##Base| 未初始化数据段的首地址
EndOfBSS DCD |Image##ZI##Limit| 未初始化数据段的结束地址
附注:|Image##RW##Limit| = |Image##ZI##Limit|
怎样调用ADS编译器产生的参数?
从汇编代码“BaseOfROM DCD |Image##RO##Base|”中,我们就可以看出汇编程序是如何调用编译器产生的参数。但是,C语言又该怎样调用这些参数呢?我摘出了一段程序可以看出。
extern char Image##RW##Limit[];()
void *mallocPt=Image##RW##Limit;()
怎样理解呢?我是这样认为的。第(1)句在地址Image##RW##Limit处定义了一个数组,显然数组的首地址就是“Image##RW##Limit”。而第二句,就去调用这个首地址。
什么可以作为只读数据段(.rodata)?
下边的代码是从main.c中摘出来的。
void Temp_function() { Uart_Printf("\nPlease input 1-11 to select test!!!\n");
struct {
void (*fun)(void);
char *tip;
}CmdTip[] = {
{ Temp_function, "Please input 1-11 to select test" } ,
{ BUZZER_PWM_Test, "Test PWM" } ,
{ RTC_Display, "RTC time display" } ,
{ Test_Adc, "Test ADC" } ,
{ KeyScan_Test, "Test interrupt and key scan" } ,
{ Test_Touchpanel, "Test Touchpanel" } ,
{ Lcd_TFT_Test, "Test TFT LCD" } ,
{ Test_Iic, "Test IIC EEPROM" } ,
{ PlayMusicTest, "UDA1341 play music" } ,
{ RecordTest, "UDA1341 record voice" } ,
{ Test_SDI, "Test SD Card" } ,
{ Camera_Test, "Test CMOS Camera"},
{ , }
};
void Main(void)
{
Beep(, );
Uart_SendByte('\n');
Uart_Printf("<***************************************>\n");
Uart_Printf(" TQ2440 Test Program\n");
Uart_Printf(" www.embedsky.net\n");
// Uart_Printf(" Build time is: %s %s\n", __DATE__ , __TIME__ );
Uart_Printf("<***************************************>\n");
while()
{
U8 idx;
Uart_Printf("\nPlease select function : \n");
for(i=; CmdTip[i].fun!=; i++)
{ Uart_Printf("%d : %s\n", i, CmdTip[i].tip);
idx = Uart_GetIntNum_GJ() ;
if(idx<i)
{
(*CmdTip[idx].fun)();
Delay();
Uart_Init( , );
}
}
}
}
通过反汇编我们可以看出,main()函数中的字符串不会被当做只读数据段处理,而被视作程序代码(.text)的一部分。只有以变量形式定义的字符串才会被视作只读数据段,例如Main()函数之前内容中的字符串。
ADS的默认连接分析及编译器产生符号解惑的更多相关文章
- Laravel 使用Voyager导致多个数据库连接总是返回默认连接?
问题与分析 最近的项目碰到一个奇怪的问题,在Laravel(5.3)中想建立多个数据库连接连到MySQL的不同数据库(另一个连接名为conn2),执行如下语句得到却发现得到的仍然是默认连接: $con ...
- 修改 EF的默认连接工厂为 Sql Server 而不是LocalDb
当你用EF6创建一个新项目,不知你是否注意到默认的连接字符串使用了LocalDb而不是SQLServer.但你如果想把默认连接改用SQLSErver而不是LocalDb.这个其实很简单:只需修改下 ...
- QSqlDatabase::addDatabase第一次运行的时候,生成SQLite文件的同时会产生一个默认连接
QSqlDatabase::addDatabase第一次运行的时候,生成SQLite文件的同时会产生一个默认连接: QSqlDatabase database = QSqlDatabase::addD ...
- Spring Boot之默认连接池配置策略
注意:如果我们使用spring-boot-starter-jdbc 或 spring-boot-starter-data-jpa “starters”坐标,Spring Boot将自动配置Hikari ...
- SpringBoot:关于默认连接池Hikari的源码剖析
1.起因 因为这两天在给公司的一个项目升级SpringBoot版本,遇到了一些坑,升级项目版本:SpringBoot1.5.x到SpringBoot2.0.x 今天早上双库操作遇到一个问题:jdbcU ...
- JVM学习三:JVM之类加载器之连接分析
学习完类加载之加载篇后,让我们继续来看加载之连接,连接分为三个步骤:验证.准备和解析三步,我们将一一分析之. 连接就是将已经读入到内存的类的二进制数据合并到虚拟机的运行时环境中去. 类加载完毕之后进入 ...
- 完整全面的Java资源库(包括构建、操作、代码分析、编译器、数据库、社区等等)
构建 这里搜集了用来构建应用程序的工具. Apache Maven:Maven使用声明进行构建并进行依赖管理,偏向于使用约定而不是配置进行构建.Maven优于Apache Ant.后者采用了一种过程化 ...
- 【转】HTTP中的长连接和短连接分析
1. HTTP协议与TCP/IP协议的关系 HTTP的长连接和短连接本质上是TCP长连接和短连接.HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议.IP协议主要解决网络路由和寻址问 ...
- centos 7.0 修改ssh默认连接22端口 和 添加防火墙firewalld 通过端口
首先 先做的就是 修改ssh的默认端口22 需要修改文件 /etc/ssh/sshd_config 使用命令 vi /etc/ssh/sshd_config [root@localhost ~]# v ...
随机推荐
- hello world是怎样运行的?
关于<深入理解计算机系统> “这本书的中译名为“深入理解计算机系统”,我非常,十分,以及百分之一百二十地不满意.我这么说的原因在于这个译法完全扭曲了书的本意.如果直译原书名,应该是类似于“ ...
- my.cnf 中字符集设置
我们的一些业务系统最近出现了一种情况,尤其是新版的ios 设备,在发布消息时,使用了表情符号时, 对gbk 字符集的数据库,写入数据库的数据,在回显时,变成 ‘口口’ 无法回显, 对utf8 ...
- quartz 报错:java.lang.classNotFoundException
最近在做一个调度平台改造的项目,quartz在测试环境跑的是单机环境,生产上两台服务器做集群. 测试环境是ok的,生产上线后报错,一个类java.lang.classNotFoundException ...
- 利用Qt调用计算器
之前有了第一个项目那么很快就会有第二个 这次 我们来调用 一些系统函数. 就不从头写了. 直接写比较重要的地方,如果又不太懂的地方欢迎小纸条或者参见利用 QT制作一个 helloworld http: ...
- AWS RDS 使用笔记
创建VPC安全组 添加VPC子网 创建RDS子网组 创建RDS参数组 创建MySQL实例 查看RDS终端节点 使用 MySQL 监视器与数据库实例上的数据库连接 安装mysql client $ su ...
- Zepto源码解读
/*******************************************************************************Zepto核心和dom操作******* ...
- U3D 2D游戏之黑暗纪元 2D游戏基础入门开发全(1)
第一个U3D 2D游戏的例子,全部自己编写,算是入门用,这里记录一下. 1.首先游戏把层次布置好,这里分为 背景层,游戏层,UI层 背景层 (Background-1):就是单纯的背景显示作用. 游戏 ...
- MYSQL的全表扫描,主键索引(聚集索引、第一索引),非主键索引(非聚集索引、第二索引),覆盖索引四种不同查询的分析
文章出处:http://inter12.iteye.com/blog/1430144 MYSQL的全表扫描,主键索引(聚集索引.第一索引),非主键索引(非聚集索引.第二索引),覆盖索引四种不同查询的分 ...
- Prism for WPF 第一讲 Event机制
在本篇文章中主要讲解在Prism中模块与模块之间事件关联的机制.在这里牵涉到三个名词:事件定义,事件发布,事件订阅. 第一:事件定义 在公共类库中定义事件. ①没有参数事件 public class ...
- Quartz2.2.1操作手册
一.初识quartz JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1") ...