程序分段和CPU内存分段是不同的概念;
现代操作系统一般都是在平坦模型下工作(整个4GB空间为一个段),编译器也是按照平坦模型为程序布局,程序中的代码和数据都在同一个段中整齐排列。《操作系统真象还原》
什么叫一个段?
段基址:段长度一样,是否就可以叫一个段?
Linux的做法
Linux怎么绕过分段机制不是很理解。有文章说,它把代码段和数据段的段基地址都设为0,段长度都为4GB。这样,两者的线性地址完全重叠。那么,两者使用地址空间不会起冲突吗?
「一个进程里的各个段都有各自对应的线性地址空间」,这是错的,一个进程只有一个用户虚拟地址空间。我们平时说的代码段,是指 readelf -S /bin/ls 输出的那些 section,而不是 x86 处理器实现的分段机制里的段。
ld.so 把 /bin/ls 中的 section 载入内存执行时,就称为 segment,你可以执行 readelf -l /bin/ls 查看 section 和 segment 的映射关系,可以看到,多个 section 可以映射为内存中的同一个 segment。
代码段中的「段」,根据上下文,可以指 section 或 segment,但不可能指 x86 处理器实现的分段机制里的段。
Linux 在实现时,完全无视分段机制,做法是:「各种段的段基地址都设为 0」。你在读文章时,凡是看到 x86 处理器分段机制里的段,直接无视即可。
为什么代码段和数据段基地址可以同时设置为0?因为分段机制已经过时了。
在Linux内核中,把代码段和数据段的段基址都设置为0,使段偏移地址等于虚拟地址(也就是线性地址),完全通过分页功能实现多进程运行。
如何保护“代码段”只读,不可写呢?
???
编译器检查,页写保护?
冯诺依曼的体系结构中必须有:代码段、数据段、堆栈段
Linux怎么绕过分段机制不是很理解。有文章说,它把代码段和数据段的段基地址都设为0,段长度都为4GB。
分段是必须的,分页是可选的,但分段又是过时的!
到了x86 64时期,cpu寄存器位数为64bit, 进入了long mode时代,intel完全弃用了分段功能,因为分页机制即有保护模式的功能,又能灵活的实现多任务。
网友评论