2010-08-17 62 views
12

我在学习汇编语言,需要澄清一些事情。如果我对这个问题有任何疑问,请纠正我,因为我对装配了解不多。程序集内存分配

我看的所有教程都将汇编程序的变量分配给内存地址,如0x0000,我可以理解您必须在汇编中手动分配内存地址,但您如何知道要使用的地址?

很明显,从最低内存地址开始是有道理的,但如果分配的变量大于0x0000处的内存,该怎么办?所讨论的变量是否会运行到0x00010x0002?如果它确实不会把其他变量分配给具有相似编号的空格(或者你不应该把它们分配给那些关闭)?

如果我有两个程序同时运行(在一个现代操作系统中)并且我在这两个程序中都使用了相同的内存地址,一个程序是否会与另一个程序发生冲突,或者OS是否只分配一个可用内存地址,而不管程序中实际写入的内容是什么?

关于这个问题的任何信息表示赞赏。

回答

18

对第二部分问题(大多数现代操作系统)的回答是虚拟内存。

您从具有物理内存的硬件层开始。这是你可以用手指戳的东西。这就是操作系统所看到的。操作系统允许您在称为虚拟内存的抽象上运行进程。

每个进程都有自己的虚拟内存空间。所以它可以假装它是唯一的进程运行,并且它有大量的内存。然后,每次访问内存时,都会提供一个虚拟地址,将其映射到物理地址。操作系统保存哪个虚拟地址映射到RAM中哪些实际物理地址的表。通常情况下,出于性能方面的考虑,这也是通过一些特殊的硬件(MMU,内存管理单元)完成的,但您也可以在软件中100%地完成。

所以当你在程序中说0x000时,这是一个虚拟地址。当您读取或写入时,它会被计算机翻译成物理地址。所以在另一个进程中,相同的虚拟地址0x000映射到不同的物理地址。这个系统可以让你编写你的程序,而不必知道有多少RAM可用,或者你的程序将被加载到什么地址。它还可以防止程序破坏属于另一个程序的内存。

至于第一部分,绝对。不同类型的数据需要不同数量的内存。在布置数据结构时,您必须知道需要多少空间。还要记住字节对齐问题。多字节数据类型(例如浮点数)通常必须从可以被2或4整除的地址或存储浮点数所需的字节数开始 - 这是处理器或RAM的要求。所以你不能只把所有的数据紧密地联系起来,一个字节在下一个字节之后,如果你想最小化未使用的内存,你必须按照特定的顺序将它们拼凑在一起,拼成一个拼图块。

+0

感谢您的详细解答!在答案的最后部分,如何精确计算每一位数据需要多少空间?手动计算一个程序的数百个变量似乎不可行。用你的话说,你如何“摆脱”? – ubiquibacon 2010-08-17 00:37:54

+0

我从未在任何大型项目中使用过程序集,但在我的操作系统类中推荐的启发式算法是按大小对变量进行排序,然后将最小的变量放在最低内存地址处。这并不总是最好的布局 - 您可能能够在大数据类型之间使用小数据类型。 您应该能够从变量的类型中知道它需要多少内存 - 请参考汇编语言的文档。请记住,一个变量在程序的整个运行过程中会占用相同数量的内存。它不能“增长”。这就是溢出发生的原因。 – 2010-08-17 00:41:40

+1

伟大的答案,只是一个更正。正确对齐数据不是关于节省空间,因为它的所有连续内存无论如何。它与数据总线如何映射到内存有关。前8位从地址0开始,接下来的8位连接到地址1.这意味着从地址0开始的16位整数可以在单次读取中读取,因为它使用数据总线的两侧。但是,如果一个16位整数从1开始,它现在必须进行两次读取才能得到整个整数。对于32位整数,出于同样的原因,它们应该在可被4整除的地址处开始。 – Despertar 2016-05-18 22:06:24

1

取决于目标和你正在谈论的内存(RAM,ROM等)的类型。如果您正在讨论RAM是一个小型嵌入式项目,您可能只有几个文件需要跟踪,微型数据表会告诉您各种存储器区域寻址。在有多个“模块”的情况下,您可以使用链接器将目标文件链接到可执行文件中。链接器可以重新分配内存地址,以便它们不重叠,也可以有一个中心文件,其中定义了所有内存位置,其他模块将其用作资源。抱歉。这是一个有很多答案的大问题。

5

这不完全是一个答案,但在这本书中有答案。我只能推荐它。它会教你基本知识,就像名字所说的那样,它是从头开始编程的。

ProgrammingGroundUp