设为首页 加入收藏

TOP

关于tcc、tlink的编译链接机制的研究(一)
2017-01-02 08:15:09 】 浏览:491
Tags:关于 tcc tlink 编译 链接 机制 研究

在c:\下建立文件夹c,并将编译器tcc.exe、连接器tlink.exe、相关文件c0s.obj、cs.lib、emu.lib、maths.lib放入文件夹中。


要搭建一个简单的C语言编译环境,需要TC2.0、c0s.obj、emu.lib、maths.lib、graphics.lib、cs.lib文件。而这里用编译器tcc.exe、连接器tlink.exe代替了TC2.0,而且相关文件也少了graphics.lib,为什么这样也可以呢?我们先尝试在新建立的环境下编译连接一个文件:



用命令“tcchello.c”编译连接生成文件hello.obj和hello.exe:



运行结果为:


在编译连接过程中,第一次我用tcchello.c编译,发现只生成了hello.obj文件,然后我又用tlinkhello.obj连接生成hello.exe文件,结果发现运行这个exe文件会出错。经过检查后发现,我把相关文件里的maths.lib错误地复制成了mathl.lib,可能在连接文件时发生了错误,导致exe文件出错。


那么这个环境与之前的环境相比,少了TC2.0、graphics.lib,多了tcc.exe、tlink.exe。在网上查阅资料发现graphics.lib是一个c语言图形库,TC2.0连接需要这个而tcc.exe不需要,我们可以理解为tc2.0在tcc.exe的基础上多了这么一个扩展,每一个库文件都相当于一个小模块,支持一种扩展。我们需要的时候,只需要添加相应的库文件就行了。


从功能上来看,tcc.exe只能从cmd编译当前目录下已存在的文件,而TC2.0则支持文件的创建、修改、保存、编译、连接,是集成了tcc.exe和tlink.exe的一个c语言小型开发平台。


那么既然新建立的环境将所需要的相关文件减少到了4个,那么是不是还可以减少呢?经过实验,我发现不论去掉哪一种相关文件,在编译时都会出错,生成一个错误的hello.obj文件,并且cmd会有相似的提示:




所以我们可以断定,在该环境下,4个相关文件必须都在才能保证编译的成功。


补充研究:在网上查询资料发现,TC2.0是一个集成的开发环境,它集成了以下文件:


INSTALL.EXE安装程序文件


TC.EXE集成编译


TCINST.EXE集成开发环境的配置设置程序


TCHELP.TCH帮助文件


THELP.COM读取


TCHELP.TCH的驻留程序


README关于TurboC的信息文件


TCCONFIG.EXE配置文件转换程序


MAKE.EXE项目管理工具


TCC.EXE命令行编译


TLINK.EXETurboC系列连接器


TLIB.EXETurboC系列库管理工具


C0.OBJ不同模式启动代码


C.LIB不同模式运行库


GRAPHICS.LIB图形库


EMU.LIB8087仿真库


FP87.LIB8087库


*.HTurboC头文件


*.BGI不同显示器图形驱动程序


*.CTurboC例行程序(源文件)


其中:上面的分别为:


TTiny(微型模式)


SSmall(小模式)


CCompact(紧凑模式)


MMedium(中型模式)


LLarge(大模式)


HHuge(巨大模式)


这个在TC的安装文件夹里其实也可以看出来:



但是我们之前的研究发现只需要需要TC2.0就可以成功编译文件,而不需要tcc.exe也在目录下,所以TC2.0是把tcc.exe集成在自己的文件内部的,而不是对外部的编译器进行调用。


查看tcc.exe的功能:



可以看到tcc的命令格式是:tcc[选项][文件名]


缺少正确的相关文件会对编译造成怎样的影响呢?我先用完整的相关文件进行编译,生成的exe文件有8kb,而删去cs.lib后进行编译,发现生成的exe文件只有536字节,比正确的文件要小得多,所以我认为在用tlink进行连接时因为相关文件的缺失导致有很大一部分相关文件都没有连接进来。


在网上查阅资料发现启动代码有TTiny(微型模式)、SSmall(小模式)、CCompact(紧凑模式)、MMedium(中型模式)、LLarge(大模式)、HHuge(巨大模式),那么分别对应的相关文件应该为:c0t.obj,ct.lib,c0s.obj,cs.lib...果然,我们在TC2.0的lib库里发现了相关文件;



我发现,其他的模式都有对应的c0*.obj和c*.lib文件,而微型模式只有c0t.obj文件,这是为什么呢?是该模式的编译特性决定他们只要用一个文件吗?我们来试试是否可以编译成功,将c0t.obj拷贝到c:\c文件夹下,再用tcc-mthello.c编译,发现可以编译连接成功,生成的exe文件也能成功运行,所以微型模式的编译是不需要特定的lib文件,这说明微型模式在编译时不需要向文件里面加入专门的库函数。



要实现打印出子函数的段地址和偏移地址,首先要知道,子函数的段地址和偏移地址放在哪里。我们在《20140426_综合研究2研究报告》中发现:(1)函数的名字就代表它的偏移地址。(2)函数的调用在汇编里是采用call-ret方法实现的。另外我们知道汇编中存储当前段地址的寄存器为CS寄存器。


首先填充main函数,分别打印每一个函数的偏移地址,以及运行函数后CS寄存器的值:



显示结果为:



发现main函数的偏移地址为21bf1的偏移地址为1faf2的偏移地址为205f3的偏移地址为210cs寄存器的一直为1a2.那么CS里的值真的是子函数的段地址的值吗我们用debug加载程序:





发现main()f1()f2()f3()的偏移地址是对的。但是段地址应为076a而不是打印出来的CS寄存器的值1a2


如果用长整形将main函数和f1的值全部打印出来:




则段地址还是1a2。但是用debug查看并不一样。那么问题在哪里呢?


在网上查看,发现有一个相似问题的解释是这样的:“调试的情况下是用调试器来实对单步断点异常的处理。加载了更多的函数。当然地址会不一样了。”


我觉得可能是直接运行和debug调试分配的内存空间不一样,如上所说,debug调试要加载更多的函数,所以main函数的段地址会相对较大。


但是这里是子函数和main函数在一个段里,所以子函数的段地址可以在主函数里用_CS


表示,如果子函数和main函数不在一个段里呢?我们知道:用tcchello.c生成的文件可有两个段,一个为代码段,一个为栈和数据段。所以函数和主函数都要在同一个代码段里。那么如果代码量超过64kb,一个段存放不下,怎么办?在网上查阅资料如下:


C语言中提供了6种编译模式,这6种模式是:


微模式(Tiny),小模式(Small),中模式(Medium),紧凑模式(Compact),大模式(Large)和巨模式(Huge)。它们之间的关系如下图所示。用户可以按照自己的程序大小及需要进行选择。
      │小程序  │大程序
  ━━━━┿━━━━━━┿━━━━━━━━
  小数据│微,小  │中
  大数据│紧凑   │大,巨


  所谓小程序就是指程序只有一个程序段,大小不超过64KB,缺省的码(函数)指针是near(近程指针)。所谓大程序就是指

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇关于C语言不定参数的研究 下一篇从汇编来看C语言之变量

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目