对于C和汇编语言的接口主要有两个问题需要解决。
一、调用者与被调用者的参数传递
这种数据传递通过堆栈完成,在执行调用时从调用程序参数表中的最后一个参数开始 ,自动依次压入堆栈;将所有参数压入堆栈后,再自动将被调用程序执行结束后的返回地址 (断点)压入堆栈,以使被调程序结束后能返回主调程序的正确位置而继续执行。例如一调用名为add汇编程序模块的主函数:main( ){ add(dest,op1,op2,flages);}。在此例中对主函数进行反汇编,主函数在调用add函数前自动组织的堆栈。
lea 0xfffffffe8(%ebp),%eax #flages数组的首地址入栈
push %eax
pushl 0xfffffff8(%ebp) #OP2入栈
pushl 0xfffffffc(%ebp) #OP1 入栈
pushl 0xfffffff0(%ebp) #dest地址入栈
call 0x80483f0 <add> #调用add函数
进入汇编子程序后,为了能正确获取主调程序并存入堆栈中的数据,被调的汇编子程序先后要做如下一些工作:
1、 保存esp的副本
进入汇编子程序后,子程序中免不了要有压栈和出栈的 *** 作,故ESP时刻在变化。为了能用 ESP访问堆栈中的参数,安全办法是一进入子程序后,先为ESP制副本,以后对传递参数的访问 都用副本进行。一般可用EBP保存ESP,如:
push %ebp
mov %ebp,%esp
2、保留数据空间
如果汇编子程序中需要一些局部数据,可以简单地减小ESP的值,以便在栈空间中保留出一段存贮区,用于存放局部数据,该区域须在子程序结束后恢复。如下语句可以保留一个局部数据区:
push %ebp
mov %ebp ,%esp
subl space,%esp;设space=4
movl $0x0,%ebp
movl $0x0,-2(%ebp)
如上语句段中,space是局部数据的总字节数。在以后的应用中,由于ESP是变化的,而 EBP是 固定的,用负偏移量可以存取局部变量。上例利用EBP及偏移量,将两个字的局部数 据初始化为0。
3、保留寄存器值
如果在被调子程序中用到ESI、EDI等其它寄存器,则应先把它们压入堆栈,以保留寄存器原值 。例如,下例就是将ESI和EDI寄存器的值压栈:
pushl %ebp
movl %ebp ,%esp
subl $space ,%esp,
pushl %esi
pushl %edi
4、获取传递参数
作完了1~3步的 *** 作后,结合上面C程序传送参数这一例子,现在栈结构如图二所示。
由此可见,EBP保留了ESP在参数传递完并将EBP压栈后的一个副本,利用EBP可以很方便地访问各参数。现假设各参数都是2字节的整数值,在小模式编译方式共占用2个字节。如果要将传递的参数op1、op2取出,并分别赋给ebx、ecx寄存器,可由下列语句完成这一功能:
movl 0x8(%ebp),%eax
movl 0xc(%ebp),%ecx
5、子程序返回值
当子程序的执行结果需要返回时,根据返回值的字长,C按如下约定接收返回值:1字节在AL 寄存器中;2字节在EAX寄存器中;4字节则高位部分在EDX中、低位部分在EAX寄存器中。C可从这些寄存器中取出返回值。
6、退出汇编子程序
结束汇编子程序的步骤如下:
1) 若ESS、EDS、ESI或EDI已被压栈,则需按保存它们的相反顺序d出它们。
2) 若在过程开始时分配了局部数据空间,则以指令 mov %esp和%ebp 恢复%esp。
3) 以指令pop %ebp 恢复%ebp ,该步是必须的。或者可以用leave语句来恢复%ebp 。它相当于movl %ebp, %esp; popl %ebp
4) 最后以ret结束汇编程序。
二、 说明和建立调用者与被调用者间的连系
为了建立调用与被调用模块间的连接关系,被调用的汇编程序应用global,说明其可被外部模块调用;而调用程序则应预先说明要引用的外部模块名。下面通过我的例子进行说明,该例是C调用add0的汇编子程序。程序清单如下:
/ addc /
#include <stdioh>
extern void add(int dest,int op1,int op2,short intflages);
/声明调用外部的汇编函数/
int main(void){
int op1,op2,result;
int dest=&result;
short int flages[4]={0,0,0,0};
printf("please enter two soure operater:");
scanf("%x%x",&op1,&op2);
add(dest,op1,op2,flages);/调用add0函数/
printf("The result of ADD is :%x/n flages N(negative) Z(zero) C(carry) V(overflow:%d,%d,%d,%d/n",dest,flages[3],flages[2],flages[1],flages[0]);
return 0;
}
#adds
text
align 2
global add
type add,function
#定义add为外部可调用的函数
add:
push %ebp #ebp寄存器内容压栈,保存add函数的上级调用函数的栈基地址
mov %esp,%ebp #esp值赋给ebp,设置add函数的栈基地址
mov 0x8(%ebp),%edx
mov 0x10(%ebp),%eax
add 0xc(%ebp),%eax
mov %eax,(%edx)
mov 0x14(%ebp),%eax
jo OF
C:
jc CF
S:
js SF
jz ZF
jmp out
OF:
movw $0x1,(%eax)
jmp C
CF:
movw $0x1,0x2(%eax)
jmp S
SF:
movw $0x1,0x6(%eax)
movw $0x0,0x4(%eax)
jmp out
ZF:
movw $0x1,0x4(%eax)
movw $0x0,0x6(%eax)
out:
leave #将ebp值赋给esp,pop先前栈内的上级函数栈的基地址给#ebp,恢复原栈基址
ret #add函数返回,回到上级的调用函数
其中text 标志一个代码段的开始,这是AT&T的段格式;global add;/n
type add,function说明add是公用的,可以由外部其它单独编译模块调用。
将C源程序以文件名addc存盘,汇编语言源程序以adds 存盘;通过MAKE进行编译和连接连接代码如下:
all: myadd
myadd: addso addco
gcc –o myadd addso adco
addso: adds
as –o addso adds
addco: addc
gcc –g –o addco addc
由上可见,在C中调用汇编模块很方便。所以我们在实际软件开发中,可以采用混合编程的技术,从而尽可能利用各语言的优势。既满足实际问题的需要,又简化设计过程,达到事半功倍的效果。
1、 *** 作复杂程度的不同
c语言,与汇编语言相比,c语言在更加接近人的一般思维,因此在程序的设计过程中比较容易 *** 作,此外在进行一些复杂的 *** 作,运算时,c语言比汇编就要简单很多,尤其是c语言中的丰富的函数库,可以直接实现一些原本很复杂的功能,并且从代码量来说任意一个c语言程序,通过反汇编之后变成汇编语言程序,其长度都可能要增加好几倍。
2、使用范围的不同
c语言程序的事件将会只是编写汇编语言程序的几分之一,从编写程序的效率上来说c语言无疑更高,此外C语言是高级程序语言因此可移植性较好,不太受到到硬件设备的限制。
在实现一个功能时,汇编语言可以直接奔着目标去,而C语言则是给你提供了一种对于对于这种问题的普遍处理办法,不具有针对性,因此会有许多多余的在这个问题中不需要的过程,因此可能回事程序较大,运行较慢。相对与汇编语言,C语言更加适合一些较大型项目的开发。
3、运行的速度和效率不同
程序没有了汇编语言计算机直接就无法运行,因为汇编语言是基于计算机底层硬件的编程,通过它实现了对cpu,内存,硬盘以及外界设备的直接 *** 作,因为直接所以汇编语言在程序的大小,执行的速度与效率方面几乎无可比拟,但是也是因为直接,所以汇编程序难以移植,且完成相同的 *** 作代码量太大,在进行一些大的项目是,单独使用汇编进行编程几乎不可能实现。
参考资料来源:百度百科—汇编语言
参考资料来源:百度百科—c语言
区别是很大的。C语言作为一种高级编程语言,是比较容易被人所理解的,但要经过编译器的编译,形成机器所能够理解的汇编语言,才能够被机器所理解。这两种语言的语法结构也很很大的差异。C语言的语言你可能已经了解一些了,那么我简单说说汇编语言。汇编语言(Assembly
Language)是面向机器的程序设计语言,实际上它是把机器码用助词符表示出来而形成的,它的语法结构一般为: *** 作码+ *** 作数1+ *** 作数2
以下是一个简单的汇编程序例子:
START:IN
AL,20H
MOV
BL,AL
IN
AL,30H
MOV
CL,AL
MOV
AX,0
ADLOP:
ADD
AL,BL
ADC
AH,0
DEC
CL
JNZ
ADLOP
HLT
以上,每行是一个语句。可见,与c语言差别很大。
一、结构不同
1、汇编程序:汇编程序输入的是用汇编语言书写的源程序,输出的是用机器语言表示的目标程序。
2、汇编源程序:汇编源程序 = 汇编指令 + 伪指令。
二、组成不同
1、汇编程序:一个汇编程序是由多个段组成的,这些段被用来存放代码、数据、或当作栈空间来使用。
2、汇编源程序:源程序中最终由计算机执行、处理的指令或数据。
三、分类不同
1、汇编程序:简单汇编程序、模块汇编程序、条件汇编程序、宏汇编程序、高级汇编程序。
2、汇编源程序:分为伪指令(编译器处理)和汇编指令(编译为机器码)。
汇编程序:把汇编语言书写的程序翻译成与之等价的机器语言程序的翻译程序。
编译程序:把用高级程序设计语言书写的源程序,翻译成等价的计算机汇编语言或机器语言的目标程序的翻译程序。
解释程序:对源程序边解释翻译成机器代码边执行的高级语言程序。
高级语言的程序的执行的途径:
1)源程序(高级语言)->编译程序->目标程序(汇编语言)->汇编程序->目标程序(机器语言)->计算结果
2)源程序(高级语言)->编译程序->目标程序(机器语言)->计算结果
3)源程序(高级语言)->解释程序(逐条读出源程序中的语句并解释执行,即在解释程序的执行过程中并不产生目标程序)->计算结果
在最早人们编写计算机程序需要直接用计算机能识别的计算机语言编写,但是工作量很繁琐,后来出现用英文字母代替二进制指令的语言,现在称为符号语言。但是用符号编写的程序计算机又不能直接识别,人们编写完符号语言后又需要转换成计算机语言让计算机运行,这样用来翻译符号语言的程序被称为汇编程序或汇编器。所以符号语言又被称为汇编语言,因此用汇编语言编写的程序叫汇编语言源程序,简称源程序,既源代码。简单来说就这么回事。 追问: 简单点说就是写出程序过程中的那些语言( 英文字母 数字 符号等)对吗? 回答: 从解释上这样理解没错,不过不同的计算机系统汇编语言源程序并不相同。 给补充一点,二进制语言和汇编语言都称为低级计算机程序设计语言。不过相对高级计算机程序语言来说你这么想也是对的。
一:机器语言,指的是CPU的 *** 作指令,这些指令只是0和1两个数字的不同组合,非常难于记忆,不利于编程,
二:汇编语言,是同CPU *** 作指令相对应的,只是把那些0和1的数字组合,写成我们便于理解的文字形式,比如:mov eax,ebx是把寄存器ebx中的数据放到eax中去,不过这种语言编程编一些小程序还行,稍微大一点,就会写的非常辛苦所以被称为低级语言
三:对于低级语言编程的不方便人们就慢慢发明了C C++语言来写程序,其实所谓语言只是人为的制定的一套规则,你按这个规则写出来的程序通过相应的编译器把你写的程序翻译成机器指令
四:JAVA,BASIC基本上同C/C++差不多,都是编程语言的一种
五:源代码就是你用各种编程语言写的程序代码,不过是不能运行的,这只是一些文本文件,用记事本都可以写出来,必须通过相应的编译器把这些源代码编译链接生成一个可执行文件,比如我们常见的exe文件
打了这么多字,不知道能不能帮上你的忙
区别如下:
(1)两者编译组成不同。汇编语言是将由0、1组成的机器语言用具有简单语义的英文代码表示,而C语言不但将许多相关的机器指令合成为单条指令,并且去掉了与具体 *** 作有关但与完成工作无关的细节,例如使用堆栈、寄存器等。
(2)两者被计算机识别的路径不同。汇编语言通常用于对硬件的直接 *** 控。而且C语言所编制的程序不能直接被计算机识别,必须经过转换才能被执行。
(3)两者用处不同。汇编语言通常用在程序中最核心的、控制硬件的代码,一方面是安全,另一方面提高运行速度。而C语言通常用在计算机外用功能上。
(4)两者学习难易程度不同。汇编语言所需要的编绘知识很多很复杂,经常被开发者使用。而C语言是一门很简单方便的语言,编程者也就不需要有太多的专业知识。
计算机语言(Computer Language)指用于人与计算机之间通讯的语言。计算机语言是人与计算机之间传递信息的媒介。计算机系统最大特征是指令通过一种语言传达给机器。计算机语言从低级到高级可以分为:
(1)机器语言,即由0、1组成的机器硬件可以识别的语言;
(2)低级语言,即汇编语言
(3)中级语言,如C语言
(4)高级语言,如C++,JAVA,C#等。
扩展资料:
如今通用的编程语言有两种形式:汇编语言和高级语言。
汇编语言和机器语言实质是相同的,都是直接对硬件 *** 作,只不过指令采用了英文缩写的标识符,容易识别和记忆。源程序经汇编生成的可执行文件不仅比较小,而且执行速度很快。
高级语言是绝大多数编程者的选择。和汇编语言相比,它不但将许多相关的机器指令合成为单条指令,并且去掉了与具体 *** 作有关但与完成工作无关的细节,例如使用堆栈、寄存器等,这样就大大简化了程序中的指令。同时,由于省略了很多细节,编程者也就不需要有太多的专业知识。
高级语言主要是相对于低级语言而言,它并不是特指某一种具体的语言,而是包括了很多编程语言,如流行的vb、vc、foxpro、delphi等,这些语言的语法、命令格式都各不相同。
高级语言所编制的程序不能直接被计算机识别,必须经过转换才能被执行,按转换方式可将它们分为两类:解释类和编译类。
参考资料:
以上就是关于谁知道汇编与c语言怎样互相调用啊,还有怎样在linux编译啊,如果可以的话,就写个简单的程序介绍。谢谢哈全部的内容,包括:谁知道汇编与c语言怎样互相调用啊,还有怎样在linux编译啊,如果可以的话,就写个简单的程序介绍。谢谢哈、汇编语言与C语言有什么区别、汇编语言与c语言的区别等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)