两种语言混合编程,首先要解决接口问题。C语言跟汇编语言之间有两种接口方式:
1、模块内接口
是指在C程序中嵌入汇编程序。使用#pragma语句来实现,其格式如下:
#pragmaASM;汇编程序
#pragmaENDASM
这种方法是通过ASM与ENDASM告诉C51编译器,中间行不用编译为汇编行,由编译控制指令来控制并将这些不用编译的行存入其中。因此,使用这种方法,在KeilC51中要作如下设置:先将嵌有汇编语句的源文件加入到要编译的工程文件中,然后右击该文件,选择“OptionforFile‘name.C’”,并将“Properties”选项卡中的“GenerateAssemblerSRCFile”和“AssembleSRCFile”两项设置为有效,再将“LinkPublOnly”项设置为无效。
这种方法可以在C语言源代码的任意位置嵌入汇编语句。
2、模块间接口
这种接口方式是把C和汇编源程序各自编辑、调试,并用各自的语言编译器进行编译,生成obj文件(即目标文件),然后用连接程序将obj文件连接起来。在这种接口方式下,需要注意C函数与汇编函数之间的参数传递,以保证模块间的数据交换。C51中提供两种参数传递的方式。
(1)通过寄存器进行参数传递
为了能产生高效代码,C51函数最多可以通过CPU寄存器传递3个参数,其传递规则如下表所示。
参数序号 | char | int | long,float | 通用指针 |
1 | R7 | R6 、R7 | R4 ~ R7 | R1 、R2 、R3 |
2 | R5 | R4 、R5 | R4 ~ R7 | R1 、R2 、R3 |
3 | R3 | R2 、R3 | -- | R1 、R2 、R3 |
(2)通过固定存储区进行参数传递
如果函数间参数传递较多,超过了寄存器的限度,那么,部分参数可以在固定的存储区域内传送。此时所使用的地址空间依赖于所选择的模式。这种参数传递技术的传递途径非常清晰,但代码效率不高、速度较慢。当然,也可以在源程序中选择编译控制命令“# pragma NOREGPARMS”,使所有参数传递都在固定的存储区域进行,以降低代码的编写难度。
在函数相互调用过程中,当函数具有返回值时,需要把函数值作为参数进行传递,这种返回值参数的传递均是通过CPU 内部寄存器完成,其传递规则如下表所示。
返回值类型 | 寄存器 | 说明 |
bit | C | 由具体标志位返回 |
char/unsingned char | R7 | 单字节由R7返回 |
int/unsigned int | R6 、R7 | 双字节高位在R6中,低位在R7中 |
long/unsigned long | R4 ~ R7 | 高位在R4中,低位在R7中 |
float | R4 ~ R7 | 32bit IEEE格式,指数和符号位在R7中 |
通用指针 | R1 ~ R3 | 存储类型在R3中,高位在R2中,低位在R1中 |