Win知识 - 程序是怎样跑起来的——函数内部的处理

简介: Win知识 - 程序是怎样跑起来的——函数内部的处理

接下来,让我们透过执行AddNum函数的源代码部分,来看一下参数的接收、返回值的返回等机制(代码清单10-5)。

代码清单10-5 函数内部的处理



ebp寄存器的值在(1)中入栈,在(5)中出栈。这主要是为了把函数中用到的ebp寄存器的内容,恢复到函数调用前的状态。在进入函数处理之前,无法确定ebp寄存器用到了什么地方,但由于函数内部也会用到ebp寄存器,所以就暂时将该值保存了起来。CPU拥有的寄存器是有数量限制的。在函数调用前,调用源有可能已经在使用ebp寄存器了。因而,在函数内部利用的寄存器,要尽量返回到函数调用前的状态。为此,我们就需要将其暂时保存在栈中,然后再在函数处理完毕之前出栈,使其返回到原来的状态。

(2)中把负责管理栈地址的esp寄存器的值赋值到了ebp寄存器中。这是因为,在mov指令中方括号内的参数,是不允许指定esp寄存器的。因此,这里就采用了不直接通过esp,而是用ebp寄存器来读写栈内容的方法。

(3)是用[ebp+8]指定栈中存储的第1个参数123,并将其读出到eax寄存器中。像这样,不使用pop指令,也可以查看栈的内容。而之所以从多个寄存器中选择了eax寄存器,是因为eax寄存器是负责运算的累加寄存器。

通过(4)的add指令,把当前eax寄存器的值同第2个参数相加后的结果存储在eax寄存器中。[ebp+12]是用来指定第2个参数456的。在C语言中,函数的返回值必须通过eax寄存器返回,这也是规定。不过,和ebp寄存器不同的是,eax寄存器的值不用还原到原始状态。至此,我们进行了很多细节的说明,其实就是希望大家了解“函数的参数是通过栈来传递,返回值是通过寄存器来返回的”这一点。

(6)中ret指令运行后,函数返回目的地的内存地址会自动出栈,据此,程序流程就会跳转返回到代码清单10-4的(6)(Call _AddNum的下一行)。这时,AddNum函数入口和出口处栈的状态变化,就如图10-5所示。将图10-4和图10-5按照(a)(b)(c)(d)(e)( f )的顺序来看的话,函数调用处理时栈的状态变化就会很清楚了。由于(a)状态时处理跳转到AddNum函数,因此(a)和(b)是同样的。同理,在(d)状态时,处理跳转到了调用源,因此(d)和(e)是同样的。在(f)状态时则进行了清理处理。栈的最高位的数据地址,是一直存储在esp寄存器中的。

图10-5 AddNum函数内部的栈状态变化

目录
相关文章
|
7月前
|
自然语言处理 Java 编译器
程序是如何运行的(一)
程序是如何运行的(一)
|
小程序 开发工具 开发者
【小程序】第一个小程序——创建小程序项目
【小程序】第一个小程序——创建小程序项目
143 0
【小程序】第一个小程序——创建小程序项目
win10隐藏正在运行的程序怎么操作_win10怎么隐藏正在运行的软件
win10隐藏正在运行的程序怎么操作_win10怎么隐藏正在运行的软件
520 0
win10隐藏正在运行的程序怎么操作_win10怎么隐藏正在运行的软件
|
C#
C# 判断当前控制台程序是否重复运行
C# 判断当前控制台程序是否重复运行
173 0
|
编译器 C++
在C++学习的过程中如何使每个 .cpp单独运行
在C++学习的过程中如何使每个 .cpp单独运行
340 1
在C++学习的过程中如何使每个 .cpp单独运行
|
存储 编译器 C语言
Win知识 - 程序是怎样跑起来的——函数调用机制
Win知识 - 程序是怎样跑起来的——函数调用机制
110 0
Win知识 - 程序是怎样跑起来的——函数调用机制
|
程序员 C语言
Win知识 - 程序是怎样跑起来的——了解程序运行方式的必要性
Win知识 - 程序是怎样跑起来的——了解程序运行方式的必要性
143 0
Win知识 - 程序是怎样跑起来的——了解程序运行方式的必要性
|
存储 API C语言
Win知识 - 程序是怎样跑起来的——应用和硬件无关?
Win知识 - 程序是怎样跑起来的——应用和硬件无关?
145 0
Win知识 - 程序是怎样跑起来的——应用和硬件无关?
Win知识 - 程序是怎样跑起来的——Win编译和链接机制
Win知识 - 程序是怎样跑起来的——Win编译和链接机制
92 0
Win知识 - 程序是怎样跑起来的——Win编译和链接机制
|
C语言
Win知识 - 程序是怎样跑起来的——条件分支的实现方法
Win知识 - 程序是怎样跑起来的——条件分支的实现方法
248 0