函数调用过程中栈到底是怎么压入和弹出的

2021-01-13 09:07:33 字数 5466 阅读 1901

1楼:匿名用户

比如:void fun(int a,int b,int c); 调用fun(1,2,3);

调用时:

-将断点程序指针压入堆栈

-将3,2,1顺序压入堆栈,并指定参数变量指针到堆栈,参数存放位置即为参数变量位置

-压栈保存现场

-执行函数

-弹栈恢复现场

-堆栈指针减掉参数占用字节数,舍弃堆栈中的参数-弹栈断点程序指针加上调用语句字节数继续执行

函数调用过程中栈到底是怎么压入和弹出的

2楼:匿名用户

这个可以用一个递归函数的过程来描述下

会比较形象

例如有递归函数

1.void example(int x)2.这段程序编译一下运行结果

比如调用example(5)

压栈过程是

5,4 , 3, 2, 1

输出,也就是弹栈过程是

1, 2, 3, 4, 5

步骤分解下

程序进入

1.example(5),走到程序第5行

发现又要进入example函数,可是

这时,example(5)还没执行结束

所以程序先把x=5存起来,这就是5入栈

他还要记录一下如果example(4)执行完后,example(5)要继续从哪行执行,也就是第6行的输出语句,所以行号也入栈,

*****这时候栈的状态是, x=5, 行号=6********记录好栈后,再执行example(4)

接着来到example(4)内部,

发现又是example(4)没执行完,又要调用函数了,这时候,他就又进行记录,我:example(4),要调用函数了,但是我还没执行完,我先把我的变量状态和运行到的位置记录下!先执行example(3),等我出来再收拾下面的**。

这时候,又开始记录了。

此时入栈 x=4,行号=6

*******这时候栈的状态**************x=4,行号=6******************x=5,行号=6***********。。。。。。。。。。。。。。

之后会一直往下进行为

x=3 x=2 x=1 x= 0当执行到example(0)的时候

栈的状态变成了

*******************************x=1,行号=6**************x=2,行号=6**************x=3,行号=6**************x=4,行号=6**************x=5,行号=6************************************注意!当x=0时,example(0)

程序走到第4行,发现函数example(0)执行完了便退出函数,然后干啥呢?

他看了看栈,哎呦我去!,我栈里还排了这么一堆东西没处理一个一个处理吧!

于是开始弹栈操作

第一步,把x=1,行号=6 弹出,此时变量x=1,执行程序第6行打印出1,函数执行完毕

然后他一看栈里还有东西,再接着弹!

第二步,把x=2,行号=6 弹出,此时变量x=2,执行程序第6行打印出2,函数执行完毕

然后他一看栈还没空管!,再接着弹!

弹弹弹弹弹弹。。。。

最后弹出x=5,行号=6,执行第六行,打印出6,退出函数发现栈空了,好了,函数也退出了,栈也空了,执行完毕最终打印结果1,2,3,4,5,6

不知道这么讲,题主能理解了么?

函数调用过程中栈到底是怎么压入和弹出的

3楼:匿名用户

调用时:

-将断点程序指针压入堆栈

-将3,2,1顺序压入堆栈,并指定参数变量指针到堆栈,参数存放位置即为参数变量位置

-压栈保存现场

-执行函数

-弹栈恢复现场

-堆栈指针减掉参数占用字节数,舍弃堆栈中的参数-弹栈断点程序指针加上调用语句字节数继续执行

什么是堆和栈?函数压栈是怎么回事?

4楼:匿名用户

什么是堆和栈?

一个由c/c++编译的程序占用的内存分为以下几个部分

1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由os** 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。

3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放

4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放

5、程序**区—存放函数体的二进制**。

函数压栈是怎么回事?

函数压栈的本质是参数传递

这又跟汇编语言连系起来了.汇编语言的过程即proc可以理解成函数

比如一个最简单的计算两数之和函数

如果用汇编来写估计是这样的

sub proc

pop ax ;从stack取a 并放在ax寄存器中

pop bx ;从stack取b 并放在bx寄存器中

add ax,bx ; 计算a+b

ret //返回

sub endp

显然要调用这个函数,你应当先把b值push进stack,然后再push a

因为stack是先进后出的

所以调用汇编像这样

比如计算4+5

push 5;

push 4;

call sub; //返回值在ax中

在这个例子中先压5或先压4得到的结果没有变化

但大多数程序,如果参数的顺序错误将是灾难性的

因为不管什么高级语言最终都要编译成汇编语言,然后是机器语言

同样下面这个c程序,计算a+b值,必然会编译成上面的汇编**

int sub(int a ,int b)

所以c在调用这个函数sub时,必须要压栈(即传入参数)但这些工作,在c语言里,并不需要你来完成.你只要写出

sub(7,9);

编译器在编译成汇编时就会自动完成相关的压栈工作.

根据函数调用方式和参数压入顺序目前存在三种约定:

stdcall

cdecl

fastcall

这都相关压栈顺序和栈的清理工作约定

他们的细节都不相同,但有一点是肯定的,参数比须从右向左压入栈中

stdcall中 函数必须自已清理栈

cdecall 由调用者清除堆栈 c的默认函数调用方式 所以这样c支持可变参数

fastcall 是把函数参数列表的前三个参数放入寄存器eax,edx,ecx,其他参数压栈

源**:

int function(int a, int b)

void main()

1.__cdecl

_function

push ebp

mov ebp, esp

mov eax, [ebp+8] ;参数1

add eax, [ebp+c] ;加上参数2

pop ebp

retn

_main

push ebp

mov ebp, esp

push 14h ;参数 2入栈

push 0ah ;参数 1入栈

call _function ;调用函数

add esp, 8 ;修正栈

xor eax, eax

pop ebp

retn

2.__fastcall

@function@8

push ebp

mov ebp, esp ;保存栈指针

sub esp, 8 ;多了两个局部变量

mov [ebp-8], edx ;保存参数 2

mov [ebp-4], ecx ;保存参数 1

mov eax, [ebp-4] ;参数 1

add eax, [ebp-8] ;加上参数 2

mov esp, ebp ;修正栈

pop ebp

retn

_main

push ebp

mov ebp, esp

mov edx, 14h ;参数 2给edx

mov ecx, 0ah ;参数 1给ecx

call @function@8 ;调用函数

xor eax, eax

pop ebp

retn

3.__stdcall

_function@8

push ebp

mov ebp, esp

mov eax, [ebp] ;参数 1

add eax, [ebp+c] ;加上参数 2

pop ebp

retn 8 ;修复栈

_main

push ebp

mov ebp, esp

push 14h ;参数 2入栈

push 0ah ;参数 1入栈

call _function@8 ;函数调用

xor eax, eax

pop ebp

retn

5楼:匿名用户

堆 heap

栈 stack

是两种不同的数据结构

stack的特点是先入后出 就像叠盘子 先放上去的盘子后拿走(底里的抽不出来自然最后才能拿走)

stack和heap放在一起讨论的话 其实不是讲的数据结构了 是说操作系统给程序分配内存的方式

对于一个程序来说 运行的时候 系统分配了一定内存给它 其中一块叫堆 一块叫栈

堆里面主要放 动态分配的内容 比如c里面用 malloc 分配到的空间 就在堆里 c++里面用new 分配到的也在堆里

栈里面放 函数的局部变量

一个函数的局部变量 会在这个函数被调用时push到栈里 这个函数返回的时候才从栈里面pop出来

栈的先入后出的顺序使得函数可以嵌套 递归 如果递归层数太多 栈也会满 就会出现栈溢出……

到文本和到数值是什么意思,易语言的 “到文本()”“ 到数值()“ 在delphi中应该用什么函数代替

1楼 葛大强 到数值 ,把非数值型的量转化成数值型的量。比如 到数值 123 就是把文本 123 变成数值123 到文本 ,把非文本型的量变成文本。比如 到文本 100 ,就把数值100变成了文本 123 文本型的量不能直接计算,必须变成数值才可以。数值型的量不能显示,只有变成文本才可以。 凡是计算...

微博中常出现的“跪最右”到底是什么意思?怎么用的

1楼 cookie张赞 微博中 跪最右 的意思如下 跪最右就是 给最右跪了 ,表示无比崇拜最右,被最右震惊或征服。 下面是比较专业的解释 举例说明 2楼 晶晶非熊猫 跪最右就是 给最右跪了 ,表示无比崇拜最右,被最右震惊或征服。 下面是比较专业的解释 3楼 最右就是第一个 点评原微博的,因为在最右边...

微博中“跪最右”什么意思,微博中常出现的“跪最右”到底是什么意思?怎么用的?

1楼 cookie张赞 微博中 跪 最右 的意思如下 跪最右就是 给最右跪了 ,表示无比崇拜最右,被最右震惊或征服。 下面是比较专业的解释 举例说明 2楼 丸纸 跪最右就是 给最右跪了 ,表示无比崇拜最右,被最右震惊或征服。 微博中常出现的 跪最右 到底是什么意思?怎么用的? 3楼 cookie张赞...