论坛: 编程破解 标题: 关于内存 复制本贴地址    
作者: kert_t8 [kert_t8]    论坛用户   登录
今天下午在读计算机组成与原理的教材(由四本据说比较著名的书杂凑而成),里面有关于内存的几句话让我搞不很清楚

[quote] In our simple model, the memory system is a linear array of bytes, and the cpu can access each memory location in a constant amount of time. While this is an effective model as far as it goes, it does not reflect the way that modern systems really work. [\quote]

按照他所说的,把内存看成线性的,CPU读取每一个内存单元的时间是相同的,这只是一个简化的模型,虽然有用并且很有效,却并没有真实地反映现在的内存系统的工作方式。

现在问题就是,难道内存不是线性的吗?

我的想法是,有这么一种可能:内存里面的模式是8bit一组组成一个byte,如果这些bytes是线性的话,一条128的内存条里面就是 128M*8 这么一个寄存器堆,这显然太荒谬了。所以我估计,实际上在电路的层面,每一个8个寄存器组成一个单元,然后单元的地址有 rows 和 cols, 这些单元又按照寄存器堆的组成原理来组成。。。。。。
而之所以可以看成线性的,因为对于一个二维数组,我们可以通过使用 row * k + col (k>max(col)) 的方式将其转化成唯一的一维地址,对于一个数组,我们也可以通过将其地址的高位和低位分别储存的方式转化成二维的地址,而对于内存地址进行这样的处理也并不复杂。
基于这样的原理,内存甚至可以是三维的,四维的

现在的问题就是,它到底是几维的呢?
286,我记得在你的置顶帖里曾经提到过内存是一维的,那是否也是一个简化以后的模型,抑或是说以前确实是一维的,但是现在有可能是两维的,三维的,而这些都取决于实际工程上的需要。
另外,这种不同的内存布局的设计对CPU读写内存的时间有没有影响?我觉得倒是没有,不过也不一定,现在我有些~~~~~~~~~~~~~

地主 发表时间: 04-12-10 10:56

回复: hackgou [hackgou]   论坛用户   登录
计算机组成和原理方面的教程侧重于计算机内部硬件的构成,或者说各个芯片以及相关引脚(包括存储器芯片的地址线以及控制信号等等)方面的研究,考虑的是如何组织这128M个存储单元,才能够让总线(BUS)更方便快捷的进行访问,而总线在访问内存时和内存芯片协同工作,实现128M的内存访问,他们之间传递的地址是物理地址,

但是软件编程人员在实际使用内存的时候,却针对不同的操作系统对内存的不同管理方式来进行编程和讨论的,比如DOS用到的简单分段,Win32用到的分页和32位方式的分段,Linux用到的分页(Linux出于移植性考虑,更侧重于分页方式)等等,这些管理方式目的有的是为了扩展对内存的可访问范围(DOS的简单分段解决16位的寄存器和20位总线地址间的矛盾,将CPU对内存的访问范围从2^6K提高到1M),有的是为了扩展可访问内存的范围(如分页和Win32方式下的分段,虽然CPU的32位寄存器可以实现4G内存访问量,但是现实中只有128M内存,如何利用现有的128M内存来实现CPU对4G内存的需求),基本上系统程序员对内存方面的讨论主题都是围绕:如何管理这128M内存来满足本操作系统对内存的需求,也就是操作系统方面的内存管理方面的问题。这是属于在逻辑方面(而非硬件方面)的讨论。

至于一维的内存方式则是指在操作系统安排下,进程(程序)的对自己可以访问内存的一种简单化的处理方式,比如执行new操作符后,就可以简单认为本教程得到了一块线形内存,而这片内存到底如何分配、如何管理以避免其他进程非法访问等等问题则由操作系统去处理,对进程本身而言就是简单的一块一维的内存区。



B1层 发表时间: 04-12-11 10:39

回复: kert_t8 [kert_t8]   论坛用户   登录
嗯~~~~~~~明白了一小半

在使用高级语言进行编程的时候,所使用的内存是对应相应命名的内存空间,这个内存空间是由操作系统分配的,大小,地址也是操作系统来管理。在这个层面上,内存应该是没有维的,离散的。不知道这个理解对不对。


但是我有几个问题:
在操作系统的层面,总的来说,不同的操作系统对内存的管理方式是不一样的,dos使用简单的分段,win32使用分页和32位方式分段(什么东西?待我在研究研究),Linux使用分页(也不懂)。这些分段分页,是分配内存的策略还是表达地址的方式?好像是表达地址的方式的机率大一点,但如果是表达地址的方式,那么岂不是汇编语言对内存地址的表达还取决于操作系统?裸机又怎么办?

引用:

总线在访问内存时和内存芯片协同工作,实现128M的内存访问,他们之间传递的地址是物理地址

什么是物理地址?
但是在程序的执行过程中,CPU得到的是一串机器码,而这个机器码是和汇编语言对应的,这一点你在置顶帖里面分析得很清楚(佩服)。那么,CPU根据机器码所提供的地址来寻址,这个地址应该就是物理地址吧?在我的理解中,总线给出的地址经过解码器解码,从而选中一大片内存单元中的某一个,而这个地址应该是一个二进制数。只不过可能这个地址无法在机器指令中完整的表达,比如在MIPS语言中的跳转指令: j label. 对应的机器码就是
0000 1000 0000 0000 0000 0000 0000 0100
其中前六位表示操作码 j, 后面的28位表示地址,具体寻址的时候,CPU将指令中的28位地址后面加两个零(左移两位,因为指令都是32位,因此对应的地址后两位都应该是零),然后将PC(program counter)的前4位加到指令中的地址前面,这样形成一个32位地址。
并且,由于可以从寄存器所存储地址读取,因此事实上这个地址是可以在指令中完整表示的。(说了这么多在说什么?) anyway.
我的意思就是,物理地址是我们指令中所给出的地址一一对应的,那么我们可以近似的认为总线传递的地址就是指令中的地址。
个中滋味,酸甜苦辣,怪怪怪


复杂,太复杂了,我还要再看看.......
谢谢憨哥

突然又看到一句:
引用:

Linux出于移植性考虑,更侧重于分页方式

怎么移植?移植到哪里?是别的非intel芯片的机器?但是在我的印象中,那需要将所有的汇编代码重写啊(是吗?)?

有些错误可能是在低级,多多包涵

再谢憨狗兄

B2层 发表时间: 04-12-11 15:35

回复: hackgou [hackgou]   论坛用户   登录
编程时的内存分配问题,在操作系统的控制下,可以看成是线形的,或者一维的。但是如何使用这一维的内存,就要根据具体需要来看了,100B的内存可以是[100]来使用,也可以是[10][10]来申请。但是无论怎样只要分配成功,从效率上来讲操作系统分配的内存是线形的,而非离散的,因为如果离散的话,那又得花费更多的CPU周期和空间去将这些离散的内存转换为线形的,得不偿失。

至于分段也好还是分页也好,无非就是解决CPU的寻址范围和实际内存大小之间的区别,在多任务系统上还涉及权限(比如某个内核内存空间对普通进程来说不可写或者不可读)等等方面的考虑。

至于机器码中的地址问题,那就是高级语言中内存访问的二进制表达,因为CPU的EU部件只负责执行语句而不负责数据的IO,数据的IO由BIU来完成,BIU要做的事情就是将指令中的地址转换到物理地址,这个转换过程需要由操作系统的配合来完成,比如Intel的386CPU如果在DOS下只能进行实模式寻址,而Win32平台上则可进行保护模式运行,他们的寻址能力也截然不同。

最后一问:
Linux的移植性:
呵呵,我们目前大多数见到的和讨论的都是Intel的×86系列CPU,而世界上还有很多其他构架的CPU:Alpha、PPC74xx、等等Linux对他们大多数平台都是支持的,当然在这方面Windos是没法比较的。这和我们现在讨论的话题离得有些远了。

B3层 发表时间: 04-12-11 20:03

回复: kert_t8 [kert_t8]   论坛用户   登录
这个......容我再细细思索一番:/pig

B4层 发表时间: 04-12-12 04:24

论坛: 编程破解

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号