计算机是怎样跑起来的pdf_程序是怎样跑起来的 -- 通过汇编语言了解程序的实际构成(中篇)...

ebp 扩展基址指针寄存器 存储数据存储领域基点的内存地址

esp 扩展栈指针寄存器 存储栈中最高位数据的内存地址

函数调用机制

函数调用是栈发挥大作用的场合。对栈进行读写的内存地址是由esp寄存器(栈指针)进行管理的。push指令和pop指令运行后,esp寄存器的值会自动进行更新(push指令是-4,pop命令是+4),因而程序员没有必要指定内存地址。

最优化功能是编译器在本地代码上费尽功夫实现的,其目的是让编译后的程序运行速度更快、文件更小。

36fd9e65281ead67c2ce36adf6afb857.png

函数内部的处理

函数的参数是通过来传递,返回值是通过寄存器来返回的。

在进入函数处理之前,无法确定ebp寄存器用到了什么地方,但由于函数内部也会用到ebp寄存器,所以就暂时将该值保存了起来。CPU拥有的寄存器是有数量限制的,在函数调用前,调用原有可能已经在使用ebp的寄存器。

ca0102ae6a8c871c66fac3ba8272ddb4.png

始终确保全局变量用的内存空间

c语言中,在函数外部定义的变量称为全局变量,在函数内部定义的变理称为局部变量。全局部变量可以在源代码的任意部分被引用,而局部变量只能在定义该变量的函数内部引用。

编译后的程序,会被归类到名为段定义的组。初始化的全局变量,会被汇总到名为_DATA的段定义,没有初始化的全局变量为被汇总到名为_BSS的段定义。指令则会汇总到名为_TEXT的段定义中。

程序运行时,没有初始化的全局变量领域都会被设定为0进行初始化。

8aa7c46b260087d1e74e264f14196450.png

临时确保局部变量用的内存空间

为什么局部变量只能在定义该变量的函数内进行引用呢?这是因为局部变量是临时保存在寄存器和栈中。

函数内部利用的栈,在函数处理完毕后会恢复到初始状态,因些局部变量的值也被销毁了,而寄存器也可能会被用于其他目的。因此,局部变量只是在函数处理运行期间临时存储在寄存器和栈上。

寄存器空闲时就使用寄存器,空间不足时就使用栈。

仅仅对局部变量进行定义是不够的,只有在给局部变量赋值时,才会分配到寄存器的内存区域。

在函数入口处为变量申请分配栈的空间的话,就必须在函数出口处进行释放。否则,经过多次调用函数后,栈的内存空间变会被用光了。


版权声明:本文为weixin_39815031原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。