C/C++汇编的接口设计 黄建华 2000年 第8期   C/C++功能强大,产生的代码效率高,是目前最流行的编程语言之一。但是效率最高的语言不是C/C++,而是汇编语言。只不过C/C++比起汇编语言来易移植,容易学习;汇编语言比C/C++功能更强大,冗余更少。因此,许多软件可以兼顾二者的优点,用C/C++和汇编语言混合编程。混合编程主要要解决的问题是二者的接口和参数传递,参数传递包括值传递、指针传递、引用传递等。下面以Borland C 3.1简单介绍一下值传递时的接口。   例程用C语言编写主程序,汇编语言编写子程序,主程序中要声明子程序的原型。主程序CMAIN.CPP如下:   //主程序cmain.cpp   #include   extern ″C″ int addition(int x,int y);   //此处声明子程序的原型,C必须大写,最后有分号。   void main()   { int x=120,y=15,z;   z=addition(x,y);   printf(″x,y,z:%d,%d,%d″,x,y,z);}   Borland C 3.1中带有用于80X86的汇编工具TASM。汇编语言中须说明为何种语言调用,调用的参数以及类型。主程序调用子程序时,从后往前向堆栈中压入参数,然后是主程序的返回地址(80X86中堆栈向低地址方向生长)。前面的主程序调用子程序时堆栈情况如^08020401a^所示:   当从堆栈中取有关参数时要用到寄存器BP,因此还须要保存BP;如果子程序中有自己的数据段,也要保存原有的DS。返回的结果如果是短整数,请放在AX中;长整数放在DX∶AX中。子程序ADDITION.ASM如下:   ;子程序addition.asm   .model small,c ;声明此为C/C++的子程序。   .486 ;可以使用486的指令,包括387。   public addition ;addition公用,可为其它程序远调用。   .code ;代码段开始。   addition proc c x:word,y:word ;addition子程序的格式。   push bp ;保存BP,   mov bp,sp ;把SP值传给BP。   mov ax,[bp+6] ;取出X。   mov bx,[bp+8] ;取出Y。   add ax,bx ;(AX)←X+Y。   pop bp ;恢复BP。   ret ;返回主程序。   addition endp   end   现在主程序和子程序都已经完成,下面可以用Borland C 3.1来编译和连接了。   首先,进入C主程序,选择“Options/Linker/Libraries”,在Libraries对话框中,选择“Turbo Vision”,以保证与tv.lib连接。   其次,新建或打开ADDITION.ASM,确认无误后选择“≡/Turbo As-sembler”,汇编成功后,选择“File/Dos Shell”,在DOS提示符下键入:   tlib tv.lib +addition.obj   如果以后ADDITION.ASM修改了,相应ADDITION.OBJ也改变了,只需键入:   tlib tv.lib -+addition.obj   现在,键入exit回到Borland C 3.1环境。   接着,新建或打开cmain.cpp,选中“Compile/Compile”,对cmain.cpp编译;选中“Compile/Link”,进行连接。   至此,一个名为cmain.exe的可执文件产生了。   下面,将浮点数的调用和返回加以介绍。   C/C++中,浮点数有两种:float,占四字节;doble,占八字节。浮点参数调进汇编语言时,仍然压入堆栈,可以用上面的方法找到参数;值返回时,只需把结果保留在80X87的TOS中即可。其余与上相同。例程如下:   //主程序fmain.cpp   #include   extern ″C″ double fsqr(double x);   void main()   {double x,y;   printf(″Enter x:″);   scanf(″%e″,&x);   y=fsqrt(x);   printf(″\nx=%e\ny=%e\n″,x,y);}   ;子程序fsqr.asm   .model small,c   . 486   public fsqrt   .code   fsqr proc c x:qword ;X为double型,占8字节。   push bp   mov bp,sp   finit ;协处理器初始化。   fld qword ptr [bp+6] ;载入X至TOS。   fsqrt ;TOS开方,结果仍在TOS内。   fwait ;与主处理器同步。   pop bp   ret   fsqr exdp   end