从C++、汇编的角度理解栈。
什么是栈?
栈是跟随线程创建,从而分配的一块内存。当线程(CPU)执行函数时,会使用该线程的栈内存来分配局部变量,因为栈的机制,会使分配局部变量非常快(原理后面再讲),这也是它存在的主要原因。
栈的工作原理
下面是二张图,一张是C++函数图,另一张是它的汇编图,我将通过它们讲解栈的工作原理。
可以看到,C++函数里,使用了3个int局部变量a、b、c,那么汇编里是怎么给它分配内存的呢,没错,只通过了一个汇编指令 sub esp,c 就实现了3个int,12(0xC)字节的内存分配。其中 esp 是个CPU寄存器,可以理解为CPU这个硬件上自带的内存,方便自己使用,不需要再请求主板对内存条进行读写(硬件的交互和电流的传播都需要时间),因此读写寄存器的速度非常快,远远超过了读写内存(内存条)的速度。
而esp寄存器,是CPU多个寄存器中的一个,里面记录的是栈顶的内存地址,sub指令是减法指令,将esp里的值减去12(0xC),也就是栈顶内存地址-12(0xC),上升了12字节内存(为什么是上升,这个后面再讲),于是就这样分配12字节的内存,也就是3个int的局部变量内存。
释放3个int局部变量内存时,也只需要 add esp,c 一个加法汇编指令,即可下压掉12个字节内存,完成内存释放。至于上面为什么没有这个指令,是因为使用 mov esp, ebp 达到了同样的效果,这里就不再进行著述,自己学汇编去,铁咩!
栈为什么快?
众所周知分配内存的速度是很慢的,它需要调操作系统的分配内存接口,告诉操作系统要分配多少内存,然后操作系统才会慢慢悠悠的去查哪里还有这么多内存,进行大量的处理和记录,最后才会将分配好的内存返回给你使用。同时释放内存也是同理,由于要清理掉内存的记录,所以速度还可能更慢。
而栈就不一样了,它是在线程创建时,就预先分配好的内存,当线程(CPU)执行函数,只需读写它的esp寄存器,上下移动栈顶内存地址,即可完成局部变量的内存分配和释放,速度当然快多了。
扩展:栈顶的上升与下降
……Only smart people can see