汇编语言与c语言混合编程例,汇编语言与C语言混合编程的接口技术

摘 要:随着网络与通信技术的发展,正在涌现出大量新的嵌入式系统,通常情况用C或者C++完成大部分的编程任务,仅有初始化部分用汇编语言完成。本文主要研究汇编语言和C语言混合编程,在当前程序开发领域提供了新的途径。

关键词:汇编程序;C语言;编排技术

1 引言

在平常编写程序时,我们一般都希望选择C、Pascal、Basic等这样的高级语言来编写,高级语言由于有编译器的支持,它们的语法更接近于自然语言,表达能力强,使用灵活,具有强大的库函数,更重要的是高级语言与机器无关,可移殖性较好,这样使程序开发周期比较短,省时省力。为了提高程序运行速度,或直接访问硬件,用汇编语言编程可以提高程序的运行效率。为了既能缩短程序开发周期,又能保证程序的执行效率,较好的解决办法是程序的框架或主体部分用C语言编写,要求执行效率高的部分用汇编语言编写。这里就涉及到了混合编程的问题,这种混合编程的方法将C语言和汇编语言的优点结合起来,所以成为目前单片机开发最流行的编程方法。混合编程的关键是解决好高级语言与汇编语言的接口问题,可采用两种方法:一是使用嵌入式汇编,即在高级语言的语句中直接使用汇编语句,这种方法比较简洁直观,但功能较弱;另一种方法是独立编程,分别产生各自的目标文件,然后经过连接,形成一个完整的程序。

2 汇编语言和C语言程序的变量相互调用

在一个工程中,一般都会由多个汇编文件和多个C/C++程序文件有机组成。在这些汇编文件和C/C++文件之间就存在变量相互访问和函数相互调用的问题。内嵌汇编不用单独编辑汇编语言文件,比较简洁,但是有诸多限制,当汇编的代码较多时一般放在单独的汇编文件中。这时就需要在汇编和C之间进行一些数据的传递,最简便的办法就是使用全局变量。

2.1 汇编程序中访问C程序变量

在C/C++程序中声明的全局变量可以被汇编程序通过地址间接访问。具体访问方法/步骤如下:

①C/C++程序中声明全局变量;②在汇编程序使用IMPORT/EXTERN伪指令声明引用该全局变量;③使用LDR伪指令读取该变量的内存地址;④根据该数据的类型使用相应的LDR或STR指令读取或设置该变量的值。对于无符号变量,使用LDRB/STRB访问char;使用LDRH/STRH访问short;使用LDR/STR访问integer。对于有符号数,使用LDRSB/LDRSH。

在汇编的源程序中调用C语言风格的字符串需要使用IMPORT伪操作。IMPORT相当于C语言中的extern关键字,告诉编译器引用的符号不是在本文件中定义的,而是在其他的源文件中定义的。

伪操作的格式:

IMPORT symbol[,WEAK]

symbol是声明的符号的名称;[,WEAK]指示编译器如果发现symbol在所有的源文件中都没有找到,那么它也不会产生任何的错误信息。

2.2 C程序中访问汇编程序变量

在汇编程序中声明的数据可以被C/C++程序所访问,具体访问方法/步骤是:在汇编程序中用EX-PORT/GLOBAL伪指令声明该符号为全局标号,可以被其他文件应用;C/C++程序中定义相应数据类型的指针变量;对该指针变量赋值为汇编程序中的全局标号,利用该指针访问汇编程序中的数据。

3 汇编语言和C语言程序相互调用

3.1 在C程序中调用汇编函数

在C程序中调用汇编函数一般情况下,在C中要调用一个汇编编写的函数,需要首先在C语言中声明此函数的函数原型,同时C语言希望所有的外部标号均以下划线/_0开头,如果汇编模块中定义的函数及变量准备供C调用,应以下划线开头。如若有函数F_Sub,要定义为供C调用的函数,在汇编程序中应定义为PUBLIC _F_Sub。因为C语言区别对待大小写字母,所以在编写准备与C模块相连接的汇编模块时,应该注意符号名的大小写,以便保持一致。以下是在C中调用汇编程序的实例:

//C语言主函数main()

void F_Sub(void); //声明要调用的函数的函数原型,此函数无参数传递

intmain(void){

while(1)

F_Sub(); //调用汇编函数

return 0;

}

//汇编子函数F_Sub()

.CODE

. PUBLIC _F_Sub

_F_Sub:

NOP

RETF

以上程序在IDE集成开发环境下编译连接后即可运行。

3.2 在汇编程序中调用C函数

在汇编函数中要调用C语言的子函数,应该根据C函数原型所要求的参数类型,分别把参数压入堆栈后,再调用C函数。调用结束后还须再进行弹栈,以恢复调用C函数前的堆栈指针。以下是汇编调用C函数的。

例如下面的程序,利用函数调用形式输出字符串″Hello world e″

Extern void display(void)L

Main()

{

display()L

}

.model small

.data

string db ″Hello world e$″

.code

public _display

_display proc

mov ah,9

mov dx,offset string

int 21h

ret

_display endp

end

说明:①在C程序中使用关键字″extern″对函数作显式说明;②对不同的存储模式要选用不同的汇编语言格式。当C程序为微型、小型、紧凑型模式时,汇编用近过程;当C程序为中型、大型、巨型模式时,汇编用远过程;③汇编程序取C的参数。远过程返回地址占四个字节,BP压入占二字节,所以第一个参数在BP+6所指向的单元,而近过程第一个参数在BP+4所指向的单元;④汇编程序中寄存器的保护。TurboC允许子过程使用SI 和DI存放局部变量,当寄存器变量多于两个时,多余部分会自动转到堆栈中存储。因此,汇编过程的格式为:

PUSH BP

MOV BP,SP

PUSH DI

PUSH SI…

…………

…………

…………

POP SI

POP DI

POP BP

RET

⑤返回值。每种C语言的数据类型都有一个标准的返回位置,一般在AX (微型、小型、紧凑型模式)或DX:AX(中型、大型、巨型模式)中,如:char,unsigned char,short int等,返回值位置为AX,且返回数据必须放置在RET指令之前。汇编子程序要定义为远过程,并用public伪指令把过程名定义为公共。

4 结束语

本文研究了汇编语言与C语言混合编程的编程问题,重点对编程时C语言与汇编语言和C语言变量与程序的相互调用问题进行了分析,并给出了实例。当采用两种或两种以上的编程语言组合编程,彼此相互调用,进行参数传递,是一种有效的程序设计方法。这种方法可以发挥各种语言的优势和特点,充分利用现有的多种实用程序、库程序等,使软件的开发周期大大缩短,是当前程序接口技术的一个重要研究和应用领域。

[参考文献]

[1]沈美明,温冬婵.IBM-PC汇编语言程序设计[M].北京:清华大学出版社, 2001.

[2]周学毛.汇编语言程序设计[M].北京:高等教育出版社,2002.

[3]张永,黄建宇,刘治生.C语言与汇编语言混合编程的研究与实现[J].计算机与数字工程,2006.

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、 实验目的和要求 掌握VC++语言和汇编语言混合编程方法,了解不同编程语言的接口方法,体会汇编语言的应用。 掌握嵌入汇编函数和汇编语言程序与VC++的混合编程方法,入口、出口参数的传递方法以及在VC++环境下混合编程的调试方法。 二、 实验条件 硬件:计算机一台 软件:Visual Studio C++ 6.0、MASM 6.0 三、 实验原理分析 在Turbo C++或Borland C++编程环境下,我们可TCC或BCC行命令把一个C语言的源程序转换成汇编语言的源程序。通过阅读汇编语言程序可以很准确地知道C语言语句的功能是如何实现的。 C语言程序转换的命令格式如下: TCC -S t1.c 或 BCC -S t1.c   ;假设其文件名为t1.c 注意:(1)TCC在TC目录下,若命令TCC/BCC不带参数的话,则将显示其使用方法。 (2)其中-S中要求S为大写。 (3)在TC上做以上操作,必须保证:TC正常安装(c:\turboc2),目录名及文件夹名都不能改变。 下面是C语言程序及其相对应的汇编语言程序,希望读者能逐行对照理解它们语句之间的转换关系,这将能进一步理解高级语言的语句功能。 (4) 汇编语言和高级语言混合编程需要解决两个主要的技术问题: 不同语言程序模块之间的连接; 调用过程中参数的传递方法。 对此不同的高级语言或同一种高级语言的不同版本所采取的具体方法不尽相同。本节主要介绍汇编语言与C/C++语言接口的基本方法。 调用协议是指在进行子程序调用,主程序向子程序传递参数以及从子程序获得返回值的约定方式。 通常参数传递的方法是:主程序使用系统堆栈向子程序传递入口参数,子程序使用CPU内部寄存器来保存向主程序的返回值。此外调用协议还将确定哪些寄存器的内容需要保护,哪些寄存器可以自由使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值