探索与发现:死机与内存的关系
互联网 发布时间:2009-04-21 01:17:31 作者:佚名
我要评论
从电脑出现至今就一直被死机伴随着,几乎没有谁的电脑从不遭遇死机。在使用过程中,偶尔一次死机应该算是正常现象,如果经常死机,电脑就存在一定的问题了。那么,电脑为什么会死机呢?有哪些因素会造成电脑死机呢?要搞清楚这些
从电脑出现至今就一直被死机伴随着,几乎没有谁的电脑从不遭遇死机。在使用过程中,偶尔一次死机应该算是正常现象,如果经常死机,电脑就存在一定的问题了。那么,电脑为什么会死机呢?有哪些因素会造成电脑死机呢?要搞清楚这些问题,首先要弄清楚,到底什么是死机?为什么会发生死机?
造成死机的原因是多种多样的,有软件问题,有硬件问题,不过,死机的本质都是一样的。
早在N年前,我主持某大学计算机专业本科生毕业答辩的时候,就向某学生提出过这样两个问题:
1.电脑死机的时候,CPU在干什么(或者说,CPU处于什么状态?)”
2.在计算机中,无论指令代码还是数据代码,都是用二进制来表示的,请问,CPU是如何判定某二进制代码是指令代码还是数据代码? //本文引用自www.jb51.net脚本之家
其实,上面两个问题的实质是一样的,主要涉及到CPU是如何取得指令和如何执行指令的,把这两个问题搞清楚了,死机的问题也就容易理解了。
首先来看看,冯.诺依曼结构的电脑是如何取得指令、又是如何执行指令的:
冯.诺依曼(1903~1957),匈牙利裔数学家,1945年戈德斯坦、勃克斯等人,联名发表了一篇长达101页纸的报告,即计算机史上著名的“101页报告”,提出了现代计算机结构的理论模型--存储程序计算机模型(Stored Program Computer),这就是今天计算机最基本的原理模型。
这种结构类型计算机工作的时候,首先必须把完成工作步骤和相关的数据用二进制代码表示出来(编写程序),然后再把它们保存在计算机的内存中,CPU依次从内存中读相关的指令代码和数据进行运算,直到完成整个运算过程并输出结果。
要完成这样的运算过程,人们在设计运算器(CPU)的时候,首先就要考虑的是,在一段内存中,CPU怎样区分指令代码和数据代码。熟悉计算机的人都清楚,指令用来确定“做什么”和“怎样做”,数据是“做”的时候需要原始数。
比如:要计算机做1 2=?中,“ ”表示要做什么和怎样做,1和2则是做的时候需要的原始数。现在假设某CPU中,“ ”用二进制“00000001”来表示,“1、2”分别用“00000001、00000010”来表示。那么,这段程序存入内存中就是这样的:
XXXX1:00000001
XXXX2:00000001
XXXX3:00000010 前面的XXXX1 XXXX2 XXXX3表示内存的地址
从上面可以看出,“ ”指令和被加数是完全相同的,当然,这是我故意这样假设的,但是,在实际情况中,这种情况是大量存在的。在正常情况下,CPU只能把XXXX1内存中的00000001作为指令,XXXX2内存中的00000001作为被加数才能得到正确的结果。那么CPU如何才能做到不把第二个00000001也当成“ ”呢?
1.人们把内存的某个地址规定为起始地址(又称为复位地址),也就是说,当计算机开机或者被强行复位(也就是机箱上那个重启动按钮按下的的时候),CPU立即跳转到这个地址中,并且把它里面的代码作为指令来执行,同时根据这个指令的长度和格式判断下一条指令在什么地方。
对于X86系列CPU(也就是现在人们常用的什么奔XX、赛XX系列),它的复位地址是FFFF0,如果表示成逻辑地址则是:FFFF:0000。对DEBUG比较熟悉的朋友或者会在一些高级语言中嵌入汇编语言的朋友可以这样做一个试验:
用DEBUG执行一条指令(这是一条无条件跳转指令):jmp FFFF:0000,或者在高级语言中嵌入这条汇编指令,执行后,你就会发现,计算机重新启动了。其实,用程序控制计算机重启的最本质的操作就是这样的。
2.给各种指令规定了相应的长度和格式。比如:某数 某数这条指令就规定:这条指令的长度是3个字节,其中第一个字节表示“ ”,后面两个字节表示被加数和加数。于是,当CPU到达这个指令后,就自动把第一个代码作为指令,后面两个代码作为数据,依次类推,第4个代码就必然是指令.....
现在假设,CPU在执行指令的时候因某种原因,误把本来是数据的代码当成了指令,结果除了是计算结果出错外死机也就是必然的了。
还是以前面那个加法程序为例:当CPU把第三个代码(也就是00000010)当成了指令,而恰好这个代码是一跳转指令,CPU的执行结果将是:XXXX3--跳转--执行--跳转--执行........进入周而复始的乱条,不过注意,虽然是在乱跳,CPU却始终是在不停的正常地执行指令,所谓的“乱”是对用户而言,对CPU来说却是正常的。
还有一种情况就是,如果恰好跳转到了FFFF:0000这个地址,计算机便重新启动了。呵呵,,这下搞清楚了为什么计算机有时会“莫名其妙地重启”了把。
有朋友可能会问,内存中怎么可能有如此多的跳转指令呢?是怎么形成的呢?
计算机中的最小存储单位是字节(8个二进制位),指令功能、长度和格式也是在一个字节中规定的。因此,平均来说,每256个代码中就有可能出现一条跳转指令(8位二进制数最多表示256)。
还有一种情况:现在计算机的内存已经达到数G的存储容量,绝大多数都不可能用到这个极限,也就是说,有相当长一段区域是空白,即使内存只有数百M的计算机中也不可能把内存用完,同样存在相当数量的空白区域。特别需要注意的是,空白区域不等于里面就没有代码。因为,在数字逻辑电路中,不可能存在“没有”这种情况,即使是表示没有(叫做“空”--NULL)也是要用一个代码来表示的(NULL用00000000)来表示,所以,空白区域内的代码是“11111111”或者干脆就是一些随机代码。X86系列的CPU“11111111”是一条单字节的指令nop--空操作指令,当CPU跳转到这些空白区域时,虽然不会发生再次跳转的现象,CPU也会逐条执行这些代码,执行到最后一个内存后,CPU将会回到内存的0号起始地方然后又从头开始执行程序。
有朋友问了,如果硬盘出错会不会死机呢?这个问题要这样看。CPU从硬盘中调入数据的时候会对硬盘数据做比较严格的校验(一般是CRC--循环冗余校验),如果校验成功,则不会死机,如果校验失败,CPU会给予用户提示“校验失败或者文件损坏”--当然也不会死机;只有在硬盘上的文件已经损坏,硬盘把数据传给CPU的时候“自己没有发现”造成的数据混乱。所以,硬盘数据损坏后,只能造成数据丢失,无法执行程序,也可能无法启动计算机。不过,有一种情况例外,那就是硬盘上的某区域做成的虚拟内存,如果这个区域损坏是有可能死机。
内存的启动监测问题,计算机在开机的时候会对内存进行检测,这种检测的方法不外乎有如下一些:
1.最简单的检测方法:把内存从头到尾读一遍,能够读出数据便认为内存正确。
2.稍微复杂一些的检测方法:把内存从头到尾读、写一遍,能够读写数据便认为内存正确。
3.再复杂一些的检测方法:把内存从头到尾读、写数遍能够读写数据便认为内存正确。
4.简单的校验检测方法:把内存从头到尾读、写数遍,读出的数据和写入的数据进行比较,能够读写、并且读的数据和写的数据相同,则认为内存正确
5.比较复杂的校验检测方法:对内存读写的数据同时进行奇偶校验和CRC校验,这种方法多用于高档服务器,同时,能够做奇偶校验的内存(ECC内存)价格比普通内存贵10倍以上(不知道为什么)。
造成死机的原因是多种多样的,有软件问题,有硬件问题,不过,死机的本质都是一样的。
早在N年前,我主持某大学计算机专业本科生毕业答辩的时候,就向某学生提出过这样两个问题:
1.电脑死机的时候,CPU在干什么(或者说,CPU处于什么状态?)”
2.在计算机中,无论指令代码还是数据代码,都是用二进制来表示的,请问,CPU是如何判定某二进制代码是指令代码还是数据代码? //本文引用自www.jb51.net脚本之家
其实,上面两个问题的实质是一样的,主要涉及到CPU是如何取得指令和如何执行指令的,把这两个问题搞清楚了,死机的问题也就容易理解了。
首先来看看,冯.诺依曼结构的电脑是如何取得指令、又是如何执行指令的:
冯.诺依曼(1903~1957),匈牙利裔数学家,1945年戈德斯坦、勃克斯等人,联名发表了一篇长达101页纸的报告,即计算机史上著名的“101页报告”,提出了现代计算机结构的理论模型--存储程序计算机模型(Stored Program Computer),这就是今天计算机最基本的原理模型。
这种结构类型计算机工作的时候,首先必须把完成工作步骤和相关的数据用二进制代码表示出来(编写程序),然后再把它们保存在计算机的内存中,CPU依次从内存中读相关的指令代码和数据进行运算,直到完成整个运算过程并输出结果。
要完成这样的运算过程,人们在设计运算器(CPU)的时候,首先就要考虑的是,在一段内存中,CPU怎样区分指令代码和数据代码。熟悉计算机的人都清楚,指令用来确定“做什么”和“怎样做”,数据是“做”的时候需要原始数。
比如:要计算机做1 2=?中,“ ”表示要做什么和怎样做,1和2则是做的时候需要的原始数。现在假设某CPU中,“ ”用二进制“00000001”来表示,“1、2”分别用“00000001、00000010”来表示。那么,这段程序存入内存中就是这样的:
XXXX1:00000001
XXXX2:00000001
XXXX3:00000010 前面的XXXX1 XXXX2 XXXX3表示内存的地址
从上面可以看出,“ ”指令和被加数是完全相同的,当然,这是我故意这样假设的,但是,在实际情况中,这种情况是大量存在的。在正常情况下,CPU只能把XXXX1内存中的00000001作为指令,XXXX2内存中的00000001作为被加数才能得到正确的结果。那么CPU如何才能做到不把第二个00000001也当成“ ”呢?
1.人们把内存的某个地址规定为起始地址(又称为复位地址),也就是说,当计算机开机或者被强行复位(也就是机箱上那个重启动按钮按下的的时候),CPU立即跳转到这个地址中,并且把它里面的代码作为指令来执行,同时根据这个指令的长度和格式判断下一条指令在什么地方。
对于X86系列CPU(也就是现在人们常用的什么奔XX、赛XX系列),它的复位地址是FFFF0,如果表示成逻辑地址则是:FFFF:0000。对DEBUG比较熟悉的朋友或者会在一些高级语言中嵌入汇编语言的朋友可以这样做一个试验:
用DEBUG执行一条指令(这是一条无条件跳转指令):jmp FFFF:0000,或者在高级语言中嵌入这条汇编指令,执行后,你就会发现,计算机重新启动了。其实,用程序控制计算机重启的最本质的操作就是这样的。
2.给各种指令规定了相应的长度和格式。比如:某数 某数这条指令就规定:这条指令的长度是3个字节,其中第一个字节表示“ ”,后面两个字节表示被加数和加数。于是,当CPU到达这个指令后,就自动把第一个代码作为指令,后面两个代码作为数据,依次类推,第4个代码就必然是指令.....
现在假设,CPU在执行指令的时候因某种原因,误把本来是数据的代码当成了指令,结果除了是计算结果出错外死机也就是必然的了。
还是以前面那个加法程序为例:当CPU把第三个代码(也就是00000010)当成了指令,而恰好这个代码是一跳转指令,CPU的执行结果将是:XXXX3--跳转--执行--跳转--执行........进入周而复始的乱条,不过注意,虽然是在乱跳,CPU却始终是在不停的正常地执行指令,所谓的“乱”是对用户而言,对CPU来说却是正常的。
还有一种情况就是,如果恰好跳转到了FFFF:0000这个地址,计算机便重新启动了。呵呵,,这下搞清楚了为什么计算机有时会“莫名其妙地重启”了把。
有朋友可能会问,内存中怎么可能有如此多的跳转指令呢?是怎么形成的呢?
计算机中的最小存储单位是字节(8个二进制位),指令功能、长度和格式也是在一个字节中规定的。因此,平均来说,每256个代码中就有可能出现一条跳转指令(8位二进制数最多表示256)。
还有一种情况:现在计算机的内存已经达到数G的存储容量,绝大多数都不可能用到这个极限,也就是说,有相当长一段区域是空白,即使内存只有数百M的计算机中也不可能把内存用完,同样存在相当数量的空白区域。特别需要注意的是,空白区域不等于里面就没有代码。因为,在数字逻辑电路中,不可能存在“没有”这种情况,即使是表示没有(叫做“空”--NULL)也是要用一个代码来表示的(NULL用00000000)来表示,所以,空白区域内的代码是“11111111”或者干脆就是一些随机代码。X86系列的CPU“11111111”是一条单字节的指令nop--空操作指令,当CPU跳转到这些空白区域时,虽然不会发生再次跳转的现象,CPU也会逐条执行这些代码,执行到最后一个内存后,CPU将会回到内存的0号起始地方然后又从头开始执行程序。
有朋友问了,如果硬盘出错会不会死机呢?这个问题要这样看。CPU从硬盘中调入数据的时候会对硬盘数据做比较严格的校验(一般是CRC--循环冗余校验),如果校验成功,则不会死机,如果校验失败,CPU会给予用户提示“校验失败或者文件损坏”--当然也不会死机;只有在硬盘上的文件已经损坏,硬盘把数据传给CPU的时候“自己没有发现”造成的数据混乱。所以,硬盘数据损坏后,只能造成数据丢失,无法执行程序,也可能无法启动计算机。不过,有一种情况例外,那就是硬盘上的某区域做成的虚拟内存,如果这个区域损坏是有可能死机。
内存的启动监测问题,计算机在开机的时候会对内存进行检测,这种检测的方法不外乎有如下一些:
1.最简单的检测方法:把内存从头到尾读一遍,能够读出数据便认为内存正确。
2.稍微复杂一些的检测方法:把内存从头到尾读、写一遍,能够读写数据便认为内存正确。
3.再复杂一些的检测方法:把内存从头到尾读、写数遍能够读写数据便认为内存正确。
4.简单的校验检测方法:把内存从头到尾读、写数遍,读出的数据和写入的数据进行比较,能够读写、并且读的数据和写的数据相同,则认为内存正确
5.比较复杂的校验检测方法:对内存读写的数据同时进行奇偶校验和CRC校验,这种方法多用于高档服务器,同时,能够做奇偶校验的内存(ECC内存)价格比普通内存贵10倍以上(不知道为什么)。
相关文章

全球首发!芝奇256GB (64GBx4) DDR5-6000 CL32超频内存套装来了
世界知名超频内存及高端电竞设备领导品牌,芝奇国际昨日宣布领先全球推出 DDR5-6000 CL32 256GB (64GBx4) 超大容量超频内存套装,下面我们来看看性能如何2025-04-22
lpddr5与ddr5内存类型的区别及内存频率对电脑性能的影响
最近在研究内存,发现有不少朋友在问LPDDR5和DDR5到底有什么区别,今天就来跟大家聊聊这两种内存的差异,帮助大家更好地选择适合自己的产品2025-03-07
全球首款双档EXPO配置内存! 佰维发布DW100 OCLAB联名款
佰维 Biwin 昨日宣布推出世界首款双档 EXPO 配置内存条 DW100 OCLAB 联名版,该内存条采用黑底缀金的优雅外观设计,专为 AMD X870 (E)、B850 平台优化2025-03-03
今天给大家种草一款近期大热的内存条——金泰克kimtigo 白月光系列 DDR5 6400 32GB(16Gx2)套装,这款内存条不仅拥有超高的频率和容量,更采用了顶级的海力士A-die颗粒,2025-02-20
ECC 内存和非 ECC内存有什么区别?内存选择的关键技术解析
ECC(内存和非ECC内存主要在功能、适用场景、传输速率以及价格等方面有所区别,下面我们就来看看详细介绍2025-02-19
RAM主要分为SRAM和DRAM两种类型,SRAM 和 DRAM 这两种类型的 RAM 目前仍然被广泛应用,但适合于各自不同的使用场景,下面本文将详细解读各类 RAM 及其特性2025-02-19
CL28超低延迟加持 频率最高8200! 金百达星刃DDR5 6000MHz C28内存实测
今天上手的这对星刃DDR5内存套装,别看频率只有6000MHz,但时序却非常低,为CL28-35-35-77,下面就一同看看该内存的具体表现2025-02-14
亦逍遥系列内存条融汇UDIMM与SODIMM双规格设计,以无与伦比的适应性,满足从桌面工作站到移动计算平台的广泛需求,详细请看下文测评2025-01-24
一键9000MT/s! 金士顿 FURY Renegade DDR5 RGB CUDIMM内存评测
Intel最新一代的酷睿Ultra 200S处理器已经上市销售,这一代处理器新增了对DDR5 CUDIMM内存的支持,可以达到比上代高出不少的内存频率,而内存厂商们也在第一时间跟进,推出2025-01-24
首款国产DDR5 32GB内存强不强? 金百达银爵DDR5调试+超频测试
首款国产DDR5内存上线了,前首发的国产DDR5内存有2个品牌,分别是金百达和光威,这次上手实测的就是搭载国产颗粒的金百达银爵16GB*2 DDR5 6000的套装2025-01-08












最新评论