内存和堆栈相关概念

内存
计算机中最小的储存单位为字节,内存也不例外,每个字节作为一个储存单元。这样就将内存划分成了上亿个内存单元,为了方便管理这些单元,计算机选择了对每一个内存单元进行编号,想要使用一个内存单元时,只需要指定该内存单元编号(即内存地址)即可。为了能编号尽量多的地址,计算机使用了一个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,就是大端模式。如果小地址处储存的是低位数据,则为小端模式。

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

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值