现在的位置: 首页 > 综合 > 正文

C语言编译模式

2013年10月09日 ⁄ 综合 ⁄ 共 1962字 ⁄ 字号 评论关闭

  编译模式是指如何在内存中放置程序代码及数据,如何分配堆栈,并确认占用的内存大小及如何存取它们,当指定内存模式(编译模式)以后,语言编译程序将按事先选择好的内存模式编译组织程序。

 

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

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

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

C语言编译模式—微模式(Tiny)
    在微模式下程序中的数据及代码均放在同一段内,即它们不超过 64KB。在微模式下代码段、堆栈段和数据段的段地址均相同,即CS=DS=SS=ES。在微模式下,数据指针都是 near,一般小程序可采用此编译模式进行编译。还可用 DOS 中的 EXE2BIN 转换程序将.EXE 程序转换成.COM 程序。代码段、数据段和堆栈段均在同一段内,对它们进行寻址时,均以同一地址偏移的参考点,具有这种特点的段又称为属于同一组段(DGROUP),栈是向上生长的,即每压栈一次,栈指针SP减2,即向地址减少的方向移动,它开始的初始值指向栈底,即0xffff(64KB)。堆是向下生长的,即向增加地址的方向改变。堆和栈地址相向生长,当两者未相遇时,便出现了自由空间。一般程序均是这种状态,当占用栈地址较多时,两者可能重合并覆盖部分堆空间。

C语言编译模式—小模式(Small)
在小模式下,程序中的代码放在64KB的代码段内,数据放在64KB的数据段内。在小模式下,栈段、附加数据段和数据段均指向同一地址,它们合三为一,即DS=SS=ES,指针都是near,一般程序均采用小模式编译。在小模式下,内存分配如下图所示。从图中可以看出数据段、堆栈段和附加段为同一段组,即它们的偏移地址均以同一段地址为参考点。

C语言编译模式—中模式(Medium)
在中模式下,所有数据放在64KB的数据段内,因而数据段内使用near,代码量可以大于64KB(允许达到1MB),因而可以在不同的代码段内,代码段使用(far远程指针)。这种编译模式适用于大代码量、小数据量的大程序。中模式下的内存分配如下图所示。

C语言编译模式—紧凑模式(Compact)

在紧凑模式下,数据量超过64KB时,可放在多个数据段中,数据段内的指针是(far)。代码量不超过64KB时,可在一个段内,因而代码段内指针为近程的(near)。但在该模式下,静态数据仍不能超过64KB,堆用far指针来存取。紧凑模式下的内存结构如下图所示。

C语言编译模式—大模式(Large)

大模式下,代码及数据均采用far指针,且都可达到1MB。静态数据仍跟紧凑模式一样,不能超过64KB。大模式下的内存结构如下图所示。

C语言编译模式—巨模式(Huge)

巨模式下,代码段及数据段均用far指针,代码分布在不同的代码段内,数据也分布在不同的数据段内,它们来自不同的源程序,大堆栈只有一个。而且静态数据大小允许超过64KB。巨模式下的内存结构如下图所示。

紧凑模式、大模式、巨模式数据区大小均允许超过64KB,即可以用数据far指针对不同数据段内的数据进行存取,它们同称为大数据存储模式。但有一点不同:紧凑模式和大模式按 C 的规定,其静态数据,即如数组、结构或其他类型的数据被定义为静态类型时,其数据量不能超过64KB,而只有巨模式才允许超过64KB。在大数据存储模式下,堆和栈分别在不同段内,多以动态数据和局部变量的形式存放,这样就不受64KB大小的限制,栈的增长不会影响堆的空间。

  无论采用哪一种编译模式,C 源程序编译生成的代码和数据量都不能超过64KB,对于超过的源程序,可以视代码或数据多少将其分解成两个或多个程序分别编译。大代码量程序要选用大代码编译模式(中模式、大模式和巨模式),大数据量程序应选用大数据编译模式(紧凑模式、大模式和巨模式),这样编译生成的.obj 文件将会带给连接程序信息,将代码和数据安排在不同段内。这样生成的.exe 文件在加载时将告诉 DOS 该程序应如何装入代码段和数据段,如何初始化寄存器。这样,就可确定在不同编译模式下开辟数据区的大小,即大于64KB,或不超过64KB。

抱歉!评论已关闭.