函数压栈顺序 -- C

基础知识:

一个程序的运行起来后,其在内存中有5个区域

1. 程序代码区

这个很简单,代码要执行,肯定要加载进内存, 我们不必关心。

2. 文字常量区

一般我们这样定义一个字符串时,其是在文字常量区的:

char* s1 = "hello, world";

char* s2 = "hello, world";

if(s1 == s2)

printf("s1和s2指向同一个在文字常量区的字符串");

这里, s1和s2指向的是同一个字符串

3. 静态存储区

全局变量,静态变量会放在这个区域,事实上,全局变量也是静态的。

以上1,2,3三个区域的内存在程序起来的时候就开辟好了的。

4. 栈

局部变量就是在栈里的。另外,函数调用时的参数也是在栈里的,这个现在不必关心

5. 堆

malloc或new出来的内存就是在堆里的,需要程序员自己管理清除。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
	压栈顺序
	从右到左,从上到下压
*/
int fun(int i, char * s)
{
	/*
		编译器中等同于
		int a;
		int b;
	*/
	int a,d;

	printf("&s = 0x%08x\n", &s);
	printf("&i = 0x%08x\n", &i);
	printf("&f = 0x%08x\n", &fun);
	printf("&a = 0x%08x\n", &a);
	printf("&d = 0x%08x\n", &d);
}
/*
[[email protected] test_class]# ./a.out
&s = 0xbff4b284
&i = 0xbff4b280
&f = 0x08048404
&a = 0xbff4b26c
&d = 0xbff4b268

*/
int
main()
{
	int i = 0x22222222;
	char * s = "aaaa";
	fun(i, s);
}
/*
	栈 -- 从高地址到低地址
	堆 -- 从低地址到高地址
	如下图
*/

函数压栈顺序 -- C

时间: 2024-10-20 07:20:33

函数压栈顺序 -- C的相关文章

函数参数的压栈顺序

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu 转载请标明来源) 先来看一道面试题: 设int arr[]={1,2,3,4 }; int *ptr=arr; printf("%d,%d",*ptr,*(++ptr)); 面试题的答案是: 2, 2 这个面试题为什么会这样呢? 原因就跟函数的压栈顺序有关,先压栈哪一个,哪一个就会被先计算,后压栈哪一个,那一个就会被后计算. 对于常见的C++程序,像缺省_cdecl或使用_stdcall的函数压栈顺序都

C语言函数参数压栈顺序为何是从右到左?(从左向右的话,碰到printf的会陷入死循环)

上学期学习了汇编语言,并在操作系统实验中使用了汇编+C语言混合编程,中间也了解了一些C语言与汇编语言的对应关系. 由于汇编语言是底层的编程语言,各种函数参数都要直接控制栈进行存取,在混合编程中,要用汇编来调用C函数,当然就要知道参数的压栈情况了. 当知道C函数的参数压栈顺序是从右到左时,我觉得很奇怪,因为大多数情况下,人们的习惯是从左到右的,难不成设计者学咱们中国古代写字从右到左的习惯不成? 当时只是记下了这个规则而已,并没有去探究这其中的缘由,后来在实验中自己用汇编实现了printf和scan

printf压栈顺序之 i++ 及 ++i

i++ 与 ++i 的不同 1 i=1; printf("%d %d\n",i,i++); //结果 2 1 2 i=1; printf("%d %d\n",i++,i); //结果 1 2 3 i=1; printf("%d %d %d\n",i,i++,i); //结果 2 1 2 4 i=1; printf("%d %d %d %d\n",i,++i,i++,i); //结果 3 3 1 3 解析: 已知前提: prin

C/C++---printf/cout 从右至左压栈顺序实例详解

__cdecl压栈顺序实例 明白计算:计算是从右到左计算的 栈和寄存器变量:x++,是将计算结果存放到栈空间,最后是要出栈的:而++x和x是将计算结果直接存放到某个寄存器变量中(是同一个),所以计算完最后输出时,++x和x的结果总是相同的. ??用个小例子来说明下: int x=5; printf("%d %d\n",x,x++); int y=5; printf("%d %d\n",y++,y); int z=5; printf("%d %d %d\n&

[Lua]Lua调用C/C++函数/库(函数压栈方式)

test.cpp文件 /*Lua调用C/C++函数/库(函数压栈方式)*/ #include<iostream> using namespace std; #include<lua.hpp> /* 当我们需要在Lua里面调用C/C++函数时,所有的函数都必须满足以下函数签名: typedef int (*lua_CFunction) (lua_State *L);换句话说,所有的函数必须接收一个lua_State作为参数,同时返回一个整数值.因为这个函数使用Lua栈作为参数,所以它

函数参数压栈,栈帧ebp,esp怎样移动的?

压栈一次esp-4,ebp不变 esp是栈顶指针寄存器,堆栈操作只和esp有关比如有一个函数a,有两个参数,一般是这样的PUSH 1 参数2压栈,esp-4PUSH 2 参数1压栈,esp-4CALL a 调用 a:PUSH EBP 保存ebpMOV EBP,ESP 改变栈帧,以后访问参数通过ebp,访问局部变量通过espSUB ESP,8 分配局部变量空间 ...ADD ESP,8POP EBP 恢复ebpRETN 8 返回,esp+8 C语句对应汇编语句: 例如函数: int aaa(int

包含min函数的栈 + 栈的压入、弹出序列

剑指offer 两道关于 数据结构——栈 的题目 1. 包含min函数的栈 简要分析一下这道题,这道题做了3遍才过,踩了一些小坑 看看示例: 得到了规律,那么关键部分的代码实现,就在于 两个栈(rawStack 和 minStack) 和 push() 方法 Stack<Integer> rawStack = new Stack<>(); Stack<Integer> minStack = new Stack<>(); public void push1(i

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

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

C利用可变参数列表统计一组数的平均值,利用函数形式参数栈原理实现指针运算

//描述:利用可变参数列表统计一组数的平均值 #include <stdarg.h> #include <stdio.h> float average(int num, ...);//函数原型:即声明 float average2(int num, ...);//num个数 void add(int num, int x, int y, int z); int main(void){ int a=10; int b=20; printf("a地址:%p b地址:%p\n&