闲谈编程之 内存

来源:互联网 发布:ubuntu安装chrome 编辑:程序博客网 时间:2024/05/01 15:21

——内存是对一堆晶体管的连续抽象


别告诉我你不知道晶体管,也别说你不知道他的工作原理,否则请看:

http://baike.baidu.com/view/30363.htm


每8个晶体管组成一个字节,每个字节都有自己的地址,这个地址就是传说中的内存地址,如果你在C中写下如下的表达式(以下在未经特殊说明的情况下,均为C语言环境):

a = 0;


a是一个符号,它有自己的真实地址,如果a是int型,并且在32位环境下,内存中将有4个字节变为0值,符号a在编译后将不复存在,替代它的将是一个固定的地址(如果生明为全局变量或者局部static变量)或者一个相对地址(函数内部的自动变量),这就是为何编译后的程序,没法还原为原始的程序代码。


当你想要运行一个程序,是操作系统把程序的映像读入了内存,这个映像是有固定的格式的,(察看资料http://baike.baidu.com/view/8358.htm#9)。每一个正在运行的程序(在32位环境)拥有独自的4GB内存,他也可以随意的使用这4GB内存,事实上是可能,因为你的计算机不会安装这么大的内存,如果超出了物理内存用量,不经常使用的内存(系统有一种方法记录内存的使用频率),就会被分页(写入硬盘上的一个文件,xp一般都是pagefile.sys),分页会导致系统运行效率成指数下降,所以程序的开发,仍然要顾及到内存的使用。


如果程序A和程序B同时访问地址01000,会发生什么?前面提到,每个程序都以为自己拥有整个足球场,所以A和B都会得到他自己想要的东西,而不会发生任何冲突,这就是虚拟内存技术从Intel 386 cpu开始,这种技术已经开始发展,虚拟内存需要CPU和操作系统同时支持。


可能你碰到过这种情况,某一个程序在运行时,突然蹦出一个对话框,告诉你程序即将关闭,因为xxxxx内存不能写入,这是因为,操作系统把内存分类——有的只能读(程序段),有的可读可写(数据段),出现上述原因,可能是一个未被初始化的指针指向了程序段,并且对指针指向的内存执行写入的操作,于是操作系统不让了,扔给你一个保护错误。


但是,仍然有可能,在数据段上写入一段有意义的程序,并且在函数返回,出栈的时候改变IP:CS指向为那一段有意义的程序(可能是一个木马,病毒的引导程序),这种方法,一般叫做缓冲区溢出攻击,攻击的方法各种各样,就像鸡蛋饼有各种做法,最初的gets()函数就被攻击过,比如向一个100个字节的数组中写入200个字节,后100个字节刚好落在程序段,当然还有一些了不起的小技巧才能欺骗cpu去执行这段非法入侵的代码。


0 0