关于tcc、tlink的编译链接机制的研究(2)

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

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

关于tcc、tlink的编译链接机制的研究

显示结果为:

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

关于tcc、tlink的编译链接机制的研究

关于tcc、tlink的编译链接机制的研究

关于tcc、tlink的编译链接机制的研究

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

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

关于tcc、tlink的编译链接机制的研究

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

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

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

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

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

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

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


  所谓小程序就是指程序只有一个程序段,大小不超过64KB,缺省的码(函数)指针是near(近程指针)。所谓大程序就是指程序只有多个程序段,每个程序段不超过64KB,但总程序量可超过64KB,缺省的码指针是far(远程指针)。小数据就是指数据只有一个数据段,缺省的数据指针是near。大数据就是指数据有多个数据段,缺省的数据指针是far。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/571e793bdc0ee11f7e1f9c7263e4d907.html