关于函数调用压栈和返回值问题的疑惑_移动开发_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > 移动开发 > 关于函数调用压栈和返回值问题的疑惑

关于函数调用压栈和返回值问题的疑惑

 2016/5/29 5:31:43  华小洲  程序员俱乐部  我要评论(0)
  • 摘要:按照C编译器的约定调用函数时压栈的顺序是从右向左,并且返回值是保存在eax寄存器当中。这个命题本该是成立的,下面用一个小程序来反汇编观察执行过程:#include<stdio.h>intadd(intx,inty){returnx+y;}intmain(){inteax=0;intz=0;intx=6;inty=5;z=add(x,y);__asm__("movl%%eax,%0":"+b"(eax):"m"(x));printf("zis%d\n",z);printf
  • 标签:函数 问题

按照C编译器的约定调用函数时压栈的顺序是从右向左,并且返回值是保存在eax寄存器当中。这个命题本该是成立的,下面用一个小程序来反汇编观察执行过程:

class="brush:cpp;gutter:true;">#include<stdio.h>

int add(int x, int y){
	return x+y;
}

int main(){
	int eax=0;
	int z =0;
	int x =6;
	int y =5;

	z=add(x,y);

	__asm__(
					"movl %%eax, %0"
				:"+b"(eax)
				:"m"(x)
					);

	printf("z is %d\n", z);
	printf("eax is %d\n", eax);
	return 0;
}

代码解释一下,asm的代码中movl %%eax, %0的意思是把寄存器eax的值赋值给咱们程序的eax变量当中。但为什么执行结果却是:

z is 11
eax is 0

理论上应该是x和y相加返回的结果才对啊。反汇编一下此exe程序:

上面是main函数

[esp+1ch]对应的是eax,[esp+18h]对应的是z,[esp+10h]对应的是x,[esp+14h]对应的是y。再看下图

先把[esp+10h]的值也就是x的值赋给eax,再把[esp+14h]的值也就是y的值赋给edx,再分别把它们赋给[esp+4]和[esp]处,注意这里没用push指令压栈,但原理却是一样,因为用的是栈指针esp。所以这里就解释了先把y压栈,再把x压栈,确实是从右向左压栈

接下来再看add调用:

先取了y的值再取x的值,相加后结果保存在eax里。然后再回到main函数

调用完add后把eax的值赋值给了z,这就说明函数的返回值确实是保存在eax中。但为什么打印出来的eax却是0呢。

接着往下看,

首先把程序中eax变量的值赋给了eax寄存器,那当然就是0了。所以现在深入理解了C语言嵌入汇编的执行过程,就算指定了"+b"赋给ebx寄存器,但编译器还是会先把变量的值赋给eax寄存器,再赋值给ebx,返回也是一样的原理,如下图:

发表评论
用户名: 匿名