变量如何寻址RAM

本文关键字:寻址 RAM 何寻址 变量 | 更新日期: 2023-09-27 18:19:48

我对此很陌生,所以如果这个问题没有意义,我提前道歉。

如果我是正确的,那么c#中的int是4个字节。如果我有声明:

int x;

我认为这占用了4个字节的内存。如果每个内存地址空间是1个字节,那么这将占用四个地址槽?如果是,x如何映射到四个地址位置?

变量如何寻址RAM

如果我有语句int x;,我会假设它占用了4个字节的内存。x如何映射到四个字节的地址?

首先,迈克是对的。C#是专门设计的,所以你不需要担心这些东西。让内存管理器为您处理它;它做得很好。

假设你真的想看看香肠是如何制作的,以供自己启迪:你的假设是不合理的此语句不需要来消耗任何内存。如果它确实导致内存被消耗,那么int将消耗四个字节的内存。

有两种方法可以使局部变量(*)不消耗内存。首先,它从未被使用过:

void M()
{
    int x;
}

编译器可以足够聪明,知道x永远不会被写入或读取,并且可以合法地完全消除它。显然,它不占用内存。

第二种不占用内存的方法是抖动选择注册本地。它可以为该局部变量指定一个机器寄存器。变量没有与其关联的地址,因为寄存器显然没有地址(**)

假设本地确实占用了内存,抖动负责跟踪该内存的位置。

如果本地是完全正常的本地,则抖动将使堆栈指针增加四个字节,从而在堆栈上保留四个字节。然后,它将把这四个字节与本地字节相关联。

如果local是匿名函数的封闭外部local、迭代器块的local或异步方法的local,那么C#编译器将生成local作为类的字段;抖动要求垃圾收集器分配类实例,并且抖动将本地实例与垃圾收集器从与该实例相关联的内存缓冲区的开头起的特定偏移量相关联。

所有这些都是实施细节,随时可能发生变化;不要依赖它。

(*)我们知道它是一个局部变量,因为您说它是语句。字段声明不是语句

(**)如果不安全代码占用了本地地址,显然无法对其进行注册。

对此有很多(我的意思是很多)可以说。你接触到的各种主题包括堆栈、符号表、内存管理、内存层次结构。。。我可以继续。

但是,既然你是新来的,我会试着给出一个更简单的答案:

当你在程序中创建一个变量(比如int)时,你告诉编译器在内存中为该数据保留一个空间。int是4个字节,因此保留了4个连续字节。你所指的记忆位置只指向开头。之后已知长度为4个字节。

现在,内存位置(在您提供的情况下)并不是以与变量相同的方式保存的。每次有一个命令需要x时,该命令都会替换为一个明确获取该内存位置的命令。换句话说,地址保存在程序的"代码"部分,而不是"数据"部分。

这只是一个真正非常的高度概述。希望它能有所帮助。

您真的不应该担心这些事情,因为在C#中,您无法编写使用这些信息的代码。

但如果你必须知道,在机器代码级别,当我们指示CPU访问x的内容时,它将使用这四个字节中第一个字节的地址。执行此操作的机器指令还将包含有关要访问的字节数的信息,在本例中为四个。

如果int x;在函数中声明,则变量将在堆栈上分配,而不是在堆或全局内存中分配。编译器符号表中x的地址将引用四字节整数的第一个字节。然而,由于它在堆栈上,因此记住的地址将是堆栈上偏移量的地址,而不是物理地址。然后,将通过使用当前堆栈指针的偏移量的指令来引用变量。

假设32位运行时,堆栈上的偏移量将被对齐,因此地址是4字节的倍数,即偏移量将以0、4、8或0x0c结束。

此外,因为80x86家族是小端序,所以整数的第一个字节将是最低有效的,而第四个字节将为最高有效的,例如,十进制值1000000将被存储为四个字节0x40 0x42 0x0f 0x00。