摘要:通过了解Turbo C和汇编兼容使用IBM PC系列机存贮系统的方法,遵循Turbo C调用汇编的各项约定, 可将汇编语言程序当作C语言的一个过程来处理, 并通过实例阐释如何实现Turbo C对汇编语言程序的调用。
关键词:Turbo C;汇编;过程调用;实例阐释
中图分类号:TP312.TC 文献标识码:A 文章编号:1007-9599 (2012) 11-0000-02
一、引言
C语言具有功能强大,方便应用,移植性高的特点,在高级编程语言方面的应用较为广泛,其缺陷表现在访问计算机系统硬件资源接口地址读写等方面明显不足。汇编语言编程工作量大,并且开发周期特别长,极为容易出错,且较难调试,但其优点为代码短,占内存小,装载速度快,可以直接控制硬件资源,综上所述杨二者之长,避二者之短,将二者混合编程,不失为一种高效程序设计开发方法。
二、Turbo C和汇编兼容使用IBM PC系列机存贮系统的方法
将C程序与汇编语言程序两种语言的代码和数据分别连在一起,组成一个可执行文件,必须进行段的组合。连接程序根据名字来识别代码和数据段,并决定它们之间的组合关系。
(一)汇编语言的段和组
汇编语言中段的格式如下??
段名 SEGMENT〔对齐类型〕〔组合类型〕〔‘类别’〕??
段名 ENDS?? ?? ?? ??
其中段名指源程序和数据段的名字,组合类型指对名字相同的各段的处理办法,类别是给同一类源码代码或数据取的名字,属同一类别的各段在内存连续存放。另外,还可使用伪指令DGROUP进行组合。
(二)Turbo C的段和组
以小型模式为例,C程序编译后的目标程序按下列方式存放,生成的代码段段名为_TEXT,类别为‘CODE’;生成的已初始化全局变量段段名为_DATA,类别为‘DATA’;生成的未初始化全局变量段段名为_BSS,类别为‘BSS’;生成的堆栈段段名为STACK,类别为‘STACK’;_DATA, _BSS, STACK合成一个组,组名为GROUP。
(三)段和组的连接
在编写汇编语言程序时按照C语言的有关规定来编制程序。以下是汇编语言程序格式:?? SEGMENT BYTE PUBLIC ‘CODE’
ASSUME CS: ,DS:
ENDS
GROUP _DATA, _BSS
SEGMENT WORD PUBLIC ‘DATA’
ENDS
_BSS SEGMENT WORD PUBLIC ‘BSS’
_BSS ENDS
END
?? ,,代表代码段名, 全局变量段名, 数组名。若按照Turbo C的缺省规定,这些名字应进行如下替换:
=_TEXT
=_DATA
=DGROUP
这样使编制的汇编语言程序和C程序编译后的.ASM文件格式上完全兼容, 达到调用的目的。
三、Turbo C过程调用汇编的各项约定
(一)存储模式约定
在混编过程中,汇编语言要和C语言的存储模式相同。在汇编语言中使用伪指令.Model***,表示在汇编语言中采用的存储模式,其中***表示上述6种模式中的一种。若C采用小模式,则在汇编语言中要使用。
(二)命名约定
C语言源程序可直接使用外部过程名调用外部过程,但在编译源程序时,为了更好地与C程序连接,编译系统自动在变量名与过程名前加一个下划线。
C语言的过程名与变量名均采用小写字母,而汇编语言则不区分大小写,为此,有效的办法是关闭在连接时将LINK程序中的大小写开关,使其能相互默认。
(三)调用约定
Turbo C调用外部过程时,均采用标准的extern关键字予以说明。当C语言调用汇编语言程序定义的变量和函数时,在C语言一侧应该用extern进行说明,其格式如下:
函数:extern 返回值类型名称(参数类型表)
变量:extern 类型变量名
而在汇编语言一侧, 必须用public。加以说明:
public _函数名
public _变量名
(四)参数传递约定
1.获取调用者的入口参数
C语言函数通过堆栈向汇编语言函数传递参数。调用汇编语言函数之前,Turbo C 先将要传给汇编语言函数的参数压入堆栈,最先压入最右边的参数,最后压入最左边的参数,如图1所示。
2.返回值的传递
当从汇编语言程序返回主调程序时,其返回值按以下方法传递给主调程序:如返回值小于或等于16位,则存放在AX中;如果返回值是32位,则存放在AX/DX 两个寄存器中,DX存高16位,AX存放低16位;如果是32位指针,则DX中存放段地址,AX中存放偏移量;如果返回值大于32位,则存放在静态变量存贮区,指向这个存贮区的指针放在AX内。
3.保护寄存器
Turbo C要求供它调用的汇编语言函数必须保护好寄存器BP、SP、CS、DS 和SS 的内容。尽管在汇编语言函数中可以改变这些寄存器的内容,但当返回时,它们的值必须与调用前相同。可以随意改变寄存器AX、BX、CX、DX和ES 及标志寄存器的内容。
寄存器SI和DI是特殊情况,因为Turbo C 将其用作寄存器变量。如果在调用汇编语言函数的C模块中启动了寄存器变量,那么在汇编语言函数就必须保护寄存器SI和DI;但若没有启动寄存器变量,就不必保护这两个寄存器。保护寄存器SI和DI,应该像保护寄存器BP那样。