《80x86汇编语言程序设计教程》习题2.45和2.46

来源:互联网 发布:5s是否支持4g网络 编辑:程序博客网 时间:2024/05/01 13:41

问:TC或BC的编译模式与存储器分段管理有什么关系?

问:TC或BC中使用的长指针的实质是什么?

编译模式是指如何在内存中放置程序代码及数据,如何分配堆栈,并确认占用的内存大小及如何存取它们,当指定内存模式(编译模式)以后,语言编译程序将按事先选择好的内存模式编译组织程序。C 语言中提供了6种编译模式,这6种模式是:微模式(Tiny),小模式(Small),中模式(Medium),紧凑模式(Compact),大模式(Large)和巨模式(Huge)。用户可以按照自己的程序大小及需要进行选择。


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

C语言编译模式—微模式(Tiny)--near指针
在微模式下程序中的数据及代码均放在同一段内,即它们不超过 64KB。在微模式下代码段、堆栈段和数据段的段地址均相同,即CS=DS=SS=ES。

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。

在tiny、small模式下,所有的函数定义、全局变量定义和指针变量的定义,如果没有显示的加上far、near、huge等关键字,都默认为使用了near关键字;在medium模式下,函数定义默认使用了far关键字,变量定义默认使用了near关键字;在compact模式下函数定义模式使用了near关键字,变量定义默认使用了far关键字;large模式下函数定义和变量定义模认使用了far关键字;huge模式下函数定义模认使用了far关键字,变量定义默认使用了huge关键字。

    near、far、huge关键字的真正含义是什么?这三个关键字只能用于修改函数、全局变量和指针变量,对于非指针类型的局部变量,这些关键字没有实际意义。这些关键字用于修饰函数时,huge的含义与far相同,用于指明该函数的调用方式为far调用方式,即调用时需要一个段值和一个段偏移组成的32bits调用地址,使用far call进行跳转,跳转前先压栈保存当前CS:IP。near修饰函数时,用于指明该函数的调用方式为near调用方式,调用时只需要一个16bits的近地址,即当前CS的段内偏移。

早期16位计算机将内存中某段开始,寻址范围为2^16地址范围之内的指针叫做短指针,寻址范围超过前述范围的叫做长指针——因为寻址长指针需要更改段寄存器的内容,做法上和短指针有一些差别。 

后来32为计算机使用“flat”内存模型,2^32地址范围(也就是4GB范围内的内存地址)内做寻址都不用修改段寄存器,就没有人再说长、短指针了。 

0 0