段所占空间大小和特点
以8086为例,假如声明一个段,不论是数据段,栈段还是代码段, 一旦段里面有内容,那么会从一个新的段地址开始开辟空间,如果代码进行了分段处理,那么就会形成16字节对齐的现象
1 | assume ds:data |
段空间占用计算公式:
如果段中的数据占用N个字节,则程序加载后,该段实际占用空间为:
1 | (N/16+1)*16 |
为什么说是现象呢
本质并不是因为段固定占用n16字节,而是因为段必须从一个新的地址段开始开辟空间,这就导致了我们认为*段一次最少拉升16字节的内存空间,必须为16的倍数**, 原因看如下代码:
1 |
|
内存分布如下:
我们发现data段并没有独占16个字节空间,而是让数据从一个新的16字节地址开始存入,段的作用是让数据在内存中的排列按照一定的布局进行排列,方便我们进行计算读取, 但是使用段的话明显会占用更多的内存空间
各个段之间内存排列分布
数据段,栈段,代码段 他们在内存中开辟的空间是根据代码由上到下依次分布的:
1 | assume ds:data,cs:code,ss:stack |
假如数据段的段地址是2000H 那么栈段的段地址为2001H, 代码段的段地址为:2002H 依次排列
如果我将各个段的代码位置调整一下,那么所在内存的位置也会跟着发生改变:
1 | assume ds:data,cs:code,ss:stack |
也就是说各个段的内存分布不是固定的, 和代码的编写有关系
如果不加start标记的话,汇编代码默认由上往下执行,cs+ip从上往下,所过之处,全部被当做代码处理, 因此即便你在数据段中存放指令,甚至打入代码起始标签也没有问题:
1 | assume cs:code,ds:data |
如果在数据段中加上代码起始标记:
1 | assume cs:code,ds:data |
段和段地址之间的关系
每个段会独占一个栈地址
1 | assume cs:code,ds:data |
内存分布如下:
咱们会发现数据段,并不是从0100:0003开始开辟16个字节的空间,而是新起一个段地址从0101:0000开始开辟, 也就是说一个段占用独立的一个栈地址
假如把段去掉:
1 | assume cs:code,ds:data |
则内存分布如下:
那么代码会依次连续进行累加填充
本文为作者原创 转载时请注明出处 谢谢
乱码三千 – 点滴积累 ,欢迎来到乱码三千技术博客站