C语言中的函数(或称为方法或者过程)是通过进程的栈空间来进行管理的,一个个函数在栈空间的表现就像是一幅一幅的图片,称为栈帧(stack frame)。其中寄存器%ebp始终指向栈帧的开始,而寄存器%esp则像游标一样在相邻两个栈帧中滑动来存取值。
下面以一个实际例子来说明:
由上图可知函数compare调用函数max, 不同颜色代表不同的栈帧,我们来开始分析汇编代码:
首先我们假设此时esp寄存器为某个值Vbase(上图中第二个箭头指向的位置);
pushl %ebp ;将%ebp寄存器的值入栈,此时Vesp = Vbase - 4;
movl %esp, %ebp; 将%esp的值赋值给%ebp,则Vebp = Vbase -4;
subl $8, %esp; 将%esp的值减去8,即分配栈空间,用于保存临时变量,这里是x和y,
;此时Vesp = Vbase-4-8 = Vbase - 12
movl $7, 4(%esp); 这里将y的值7存到Vesp+4指定的地址
movl $5, %esp;这里将x的值5存储到Vesp指定的地址
call max;这里调用max函数,call指令会首先将函数执行完后的返回地址(即call后面第一条指令的虚拟地址)压入栈
;中,此时Vesp = Vbase - 16
//*************************************这里进入max函数********************************************************//
pushl %ebp;将%ebp寄存器的值入栈,此时Vesp = Vbase - 20;
movl %esp, %ebp; 将%esp的值赋值给ebp,则Vebp = Vbase -20;
movl 12(%ebp), %eax;将Vbase - 8地址即y的值存到%eax寄存器中
cmpl %eax, 8(%ebp);将y 与Vbase - 12地址即x的值作比较
setg %al;如果x大于y设置%al为1,相反设置为0
movzbl %al, %eax;用零扩展位方式将al的值扩展到%eax中,即清除%eax的高24位
popl %ebp;将进入函数时的%ebp值出栈存入%ebp寄存器中,此时Vesp = Vbase -16,指向“返回地址”
ret;将Vesp指向的地址的值转入%eip寄存器,然后让%esp+4,即出栈,此时Vesp = Vbase -12,指向x
//*************************************这里退出max函数********************************************************//
testl %eax, %eax;这里比较max的返回值是不是为1,函数的返回值一般存在eax寄存器中
mov $35, %edx; 这里编译器将x*y直接优化成35,将该值存到%edx寄存器中
cmovne %edx, %eax;这里用到了tesl的值,如果返回值为1,则将%edx的值赋值到%eax中
leave;将%ebp的值(即compare函数第二个语句中的%ebp值)赋值给%esp,即回收分配给x和y的空间,
;然后将%esp指向的栈顶地址中的值赋值给%ebp
ret;将Vesp指向的地址的值转入%eip寄存器,然后让Vesp+4,即出栈,此时Vesp = Vbase
扩展知识:由于芯片中寄存器是被所有方法共有的,为了不让被调用者破坏调用者的数据,必须遵循下面的规则:
1.寄存器%eax,%edx和%ecx作为调用者保存寄存器,如果函数P调用函数Q,那么Q可以任意使用这些寄存器,不用
担心会损坏P的数据
2.寄存器%ebx,%esi和%edi为被调用者保存寄存器,如果函数P调用函数Q,如果Q需要用到这些寄存器的时候,必须先
保存,当函数退出时恢复该寄存器的值。
相关推荐
汇编语言实现对引脚底层的配置,使用C语言调用汇编语言函数进行点灯.zip汇编语言实现对引脚底层的配置,使用C语言调用汇编语言函数进行点灯.zip汇编语言实现对引脚底层的配置,使用C语言调用汇编语言函数进行点灯....
KEIL 51编程中关于c语言中嵌入汇编代码的初步精简讲解希望对你有所帮助汇编
51单片机C语言编程中嵌入汇编的一段实例
8051C语言调用汇编详细注释源代码
利用反汇编手段解析c语言函数,讲解详细,不错的一本书
p.c生成语法树,table.c是符号表,g.c是转化成具体masm32代码,只支持char,short,int,double四种类型数据,其他的有兴趣的可以自己修改增加,由于masm32限制,目前该编译器只支持局部变量在函数开头定义,全局变量不...
本例为16/16位定点除法C语言调用汇编函数的程序 C语言调用汇编函数时传递了两个参数 汇编函数中使用了C变量 调用ASM_DIV函数计算后 商在ACCB中 余数在ACCC中
C语言字符串操作函数[汇编].pdf
C语言函数调用汇编语言函数[归纳].pdf
结合汇编讲解了c语言汇中函数参数是如何传递,如何调用的
在DEV_C++中演示建立汇编函数的框架的详细步骤。
用ARM汇编子程序实现求以2为底的对数。...其中C语言程序是入口控制程序,调用ARM的汇编语言程序,以半主机方式(模拟器方式)完成输入和输出,以及代码的调试。要求对C代码和ARM汇编代码地语句加以注释。
C语言中常用函数大全[汇编].pdf
使用C及汇编语言编写的延时程序,分别使用两种语言,及反汇编的分析
C语言是一个强大的语言,特别是对于嵌入式开发过程中有时需要反汇编分析代码中存在的问题,函数是C语言中的难点,关于函数的调用也是很多人不能理解的,很多知道的也是一知半解。对C语言的调用有了一个比较清晰的...
C语言函数题库汇编.pdf
C语言是一种计算机程序设计语言,它既具有高级语言的特点,又具有汇编语言的特点。它由美国贝尔研究所的D.M.Ritchie于1972年推出,1978年后,C语言已先后被移到大、中、小及微型机上,它可以作为工作系统设计语言,...
对DSP进行优化的时候,难免会用到线性汇编,今天找了一上午关于在C中调用线性汇编的程序,发现网上资料很少,这里自己做一个记录。
这是一个简单的例子,说明了C程序和汇编程序的关系。