内存和堆栈相关概念

  • Post author:
  • Post category:其他



内存


计算机中最小的储存单位为字节,内存也不例外,每个字节作为一个储存单元。这样就将内存划分成了上亿个内存单元,为了方便管理这些单元,计算机选择了对每一个内存单元进行编号,想要使用一个内存单元时,只需要指定该内存单元编号(即内存地址)即可。为了能编号尽量多的地址,计算机使用了一个4字节的数来编址内存,这样可以对2^32 块内存进行编址,每个块为1byte,2^32 byte = 4Gb,可以编址的内存大小为4G大小。


堆栈


程序运行时候并不会立即分配所有的内存给程序使用,会初始化一定大小的内存区域给程序,这个内存空间中的内存块可以被程序使用,用来储存程序中的数据。这段空间是从大地址的内存块开始使用的,为了查看当前的栈使用到哪一块地址内存单元,在ESP寄存器中记录了当前使用的内存位置,如果添加一个数据,将会在该位置添加,然后ESP继续向前移动一个位置。所以ESP寄存器记录的当前位置,就是下一个数据插入时的位置。这个指针我们称为栈顶指针,该指针随着数据的添加(push)和取出(pop)移动。同样的,EBP中记录了一个栈开始的地址,被成为栈底指针,该地址通常不会改变,只有在开辟一个新的栈空间,例如执行一个函数调用时,需要为函数重新记录一段新的函数空间时,才会改变栈底的位置。但是在改变栈底指针时,会将原来的栈底位置入栈保存,便于将来恢复到原栈底位置。


堆栈提升


我们知道,在高级语言中,当我们执行一个函数调用,将会开辟一个新的栈空间,此时就需要进行堆栈提升,此时需要更改ESP和EBP寄存器中记录的栈底和栈底指针,这样函数中产生的值将不会影响原栈空间(黄色部分)的数据。右图为堆栈提升后的结果,此时push数据会从1005开始添加,pop也只能到1005这个地址的数据,无法再向下pop,这样将无法影响元堆栈的内容。

在这里插入图片描述


堆栈平衡


堆栈平衡实际上就是恢复堆栈内容,例如执行一次函数操作时,进行堆栈提升,开辟新的空间来供函数使用,当函数执行结束后,应该让栈底和栈顶指针恢复到原来的位置。

简述过程为

1.将ESP寄存器中的值,更改为EBP的值,这样栈顶到了目前栈底的位置。ESP=1005

2.将EBP寄存器指向的内存地址中的值取出,即1000,将EBP寄存器的值改为该值1000。这样EBP回到了1000的位置。

由此完成了堆栈的恢复,实现了堆栈平衡


数据宽度


汇编语言中有三种数据宽度,分别为

BYTE:一个字节宽度,占8位

WORD:字,两个字节宽度,占16位

DOUBLEWORD:双字,四个字节宽度,占32位。


大小端模式


内存是从小到大进行编址的,储存一个多字节的数据时候,如果内存的小地址存储多字节数据的高位,就是大端模式。也就是说,先取数据的高位进行储存,再依次取低位储存。例如一个字符串”abcd”,a为数据的高位,d为低位,内存会取出四个连续的内存空间来储存这个字符串。如果这段连续内存的小地址上储存的时a然后依次为bcd,就是大端模式。如果小地址处储存的是低位数据,则为小端模式。

数据储存为大端或者小端模式是由编译器决定的。


补一句,所有寄存器里存的都是地址



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