3.4 C与汇编程序的相互调用
为了提高代码执行效率,内核源代码中有些地方直接使用了汇编语言编制。这就会涉及在两种语言编制的程序之间相互调用的问题。
函数调用包括从一块代码到另一块代码之间的双向数据传递和执行控制转移。数据传递通过函数参数和返回值来进行。另外,我们还需要在进入函数是为函数的局部变量分配空间,并在函数退出时回收者部分空间。Intel 8086 CPU为控制传递提供了简单的指令,而数据的传递和局部变量存储空间的分配与回收则通过栈操作来实现。
1.栈帧结构和控制转移权方式
大多数CPU的程序实现使用栈来支持函数调用操作。栈被用来传递函数参数、存储返回信息、临时保存寄存器原有值和存储局部数据。单个函数调用操作所使用的部分被称为栈帧(stack frame)结构。栈帧结构的两端由两个指针指定。寄存器ebp通常用作帧指针,esp用作栈指针。程序执行过程中,栈指针会随着数据的入栈和出栈而移动,因此函数中对大部分数据的访问都是基于帧指针ebp进行。
对于函数A调用函数B的情况,传递给B的参数包含在A的栈帧中。当A调用B时,函数A的返回地址被压入栈中,该位置也明确指明A栈帧的结束处。而B的栈帧从随后的栈部分开始。B函数同样也使用栈来保存不能放在寄存器中的局部变量值。例如:由于通常CPU的寄存器数量有限而不能存放函数的所有局部数据,或者有些局部变量是数组或结构,因此必须使用数组或结构引用来访问。还有就是C语言地址操作符“&”被应用到一个局部变量上时,我们就需要为该变量生成一个地址,即为该变量的地址指针分配一块空间。最后,B函数会使用栈来保存调用任何其他函数的参数。
栈是往小(低)地址方向扩展的,而esp指向当前栈顶处元素。通过使用push和pop指令我们可以把数据压入栈中或从栈中弹出。对于没有指定初始值的数据所需要的空间,我们可以通过把栈指针递减适当的值来做到。类似的可以回收已经分配的空间。
指令CALL和RET用来处理函数调用和返回操作。调用指令CALL的作用是把返回地址压入栈中并且跳转到被调用函数开始处执行。返回地址是程序中紧随调用指令CALL后面的一条指令的地址。因此当被调用函数返回是就从该位置继续执行。返回指令RET用于弹出栈顶处的地址并跳转到该地址处。在使用该指令之前,应该先正确处理栈中内容,使得当前栈指针所指内容正是先前CALL指令保存的返回地址。另外,若返回值是一个整数或者一个指针,那么寄存器eax将被默认用来传递返回值。
尽管某一个时刻只有一个函数在执行,但是我们还是需要确认在一个函数调用其他函数时,被调用者不会修改或覆盖调用者今后要用到的寄存器内容。因此Intel CPU采用了所有函数必须遵守的寄存器用法统一惯例。该惯例指明,寄存器eax、edx、ecx的内容必须由调用者自己负责保存。当函数A调用函数B时,B可以在不用保存这些寄存器的内容的情况下任意使用它们而不会毁坏函数A所需要的任何数据。另外,寄存器ebx、esi和edi的内容则必须由被调用者来保护。当被调用者需要使用到这些寄存器中的任何一个时,必须首先在栈中保存其内容,并在退出时恢复这些寄存器的内容。因为调用者A并不负责保存这些寄存器的内容,但可能在以后的操作中还需要用到原先的值。还有寄存器ebp和esp也必须遵守第二个惯例用法。
3.4 C与汇编程序的相互调用的更多相关文章
- A(51)和C(51)相互调用
C语言是一种编译型程序设计语言,它兼顾了多种高级语言的特点,并可以调用汇编语言的子程序.用C语言设计开发微控制器程序已成为一种必然的趋势.Franklin C51是一种专门针对Intel 8051系列 ...
- Android和JavaScript相互调用的方法
转载地址:http://www.jb51.net/article/77206.htm 这篇文章主要介绍了Android和JavaScript相互调用的方法,实例分析了Android的WebView执行 ...
- 多个Activity相互调用和Intent
MainActivity.java和OtherActivity.java的相互调用 首先MainActivity.java是Android程序自带的,新建一个类OtherActiviy extends ...
- JS代码和OC代码的相互调用
JS调用OC 很多应用里面或多或少的调用了网页,来达到绚丽的效果,所谓的JS调用OC.....举个例子吧,网页上有个按钮 点击按钮跳转界面,跳转的动作由OC的代码实现. OC调用JS 还是举个例子,我 ...
- C程序与Lua脚本相互调用
Lua脚本是一种可用于C程序开发/测试的工具,本篇介绍一下C程序与Lua脚本如何进行相互调用,更加详细的操作参见<Programing in Lua>.本文分为3个部分:1.Windows ...
- Unity3D中C#和js方法相互调用
通过查找资料,Unity3D中C#和js要相互调用彼此的方法,js文件必须放在"Standard Assets". "Pro Standard Assets" ...
- Unity3d 脚本相互调用
unity中三种调用其他脚本函数的方法 第一种,被调用脚本函数为static类型,调用时直接用 脚本名.函数名().很不实用…… 第二种,GameObject.Find("脚本所在物体名& ...
- Lua与C++相互调用
{--1.环境--} 为了快速入手,使用了小巧快速的vc++6.0编译器 以及在官网下载了Lua安装包..官网地址{--http://10.21.210.18/seeyon/index.jsp--} ...
- 关于action script与js相互调用的Security Error问题
大家都知道,as和js相互调用可以通过ExternalInterface.call和ExternalInterface.addCallback来进行. 比较好的做法是使用之前通过ExternalInt ...
随机推荐
- Common Subsequence
#include<cstdio> #include<iostream> #include<cmath> #include<string> #includ ...
- Putty工具包简单使用
Putty工具包简单使用 一.Putty简介 Putty是一款远程登录工具,用它可以非常方便的登录到Linux服务器上进行各种操作(命令行方式).Putty完全免费,而且无需安装(双击即可运行),支持 ...
- COJ 0579 4020求次短路的长度
4020求次短路的长度 难度级别:C: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 在一个地图上共有N个路口(编号分别为1到N),R条道路( ...
- HDU 1045 Fire Net(图匹配)
题目大意: 这个是以前做过的一道DFS题目,当时是完全暴力写的. 给你一个N代表是N*N的矩阵,矩阵内 ‘X’代表墙, ‘.’代表通道. 问这个矩阵内最多可以放几个碉堡, 碉堡不能在同一行或者同一列, ...
- 【转】Java生成对应字符串的MD5密码模块
原文网址:http://www.cnblogs.com/xudong-bupt/archive/2013/05/10/3070899.html (1)一般使用的数据库中都会保存用户名和密码,其中密码不 ...
- Java中BitSet使用(转)
java.util.BitSet,采用位运算: 官方API:http://docs.oracle.com/javase/7/docs/api/java/util/BitSet.html 摘要: Bit ...
- (转载)PHP array_merge() 函数
(转载)http://www.w3school.com.cn/php/func_array_merge.asp PHP Array 函数 定义和用法 array_merge() 函数把两个或多个数组合 ...
- delphi 自定义消息
delphi 自定义消息 消息描述 Tmsg是 Windows系统用来记录描述一个具体的windows消息的.就是windows 用于封装应用程序及系统程序发生的消息,它是操作系统使用 ...
- 【转】C#读取文件时的共享方式
string sFileName = @"C:\Exchange.dat";System.IO.StreamReader file = new System.IO.StreamRe ...
- H - Antenna Placement- hdu 3020(二分图匹配)
题意:每个 ‘*’都需要一个1*2的东西覆盖,问最少需要多少个1*2的东西来覆盖这些‘*’ 分析:只需要求出来最多有多少个完全覆盖的,然后加上那些不能被完全覆盖的点即可..把G题的代码随便修改了一下就 ...