在C/ c++或任何其他类似语言中,对变量或数据类型应用&符号时返回的地址类型

What type of address returned on applying ampersand to a variable or a data type in C/C++ or in any other such language?

本文关键字:应用 数据类型 变量 符号 返回 类型 地址 任何 c++ 其他 语言      更新时间:2023-10-16

自从我在操作系统课上听到虚拟和物理内存的概念以来,这是一个非常基本的问题,一直困扰着我。现在我知道,在加载时和编译时,虚拟地址和逻辑地址绑定方案是相同的,但在执行时它们不同。

首先,为什么在编译和加载时生成虚拟地址是有益的,以及当我们应用&号操作符来获取变量、原始数据类型、用户定义类型和函数定义地址的地址时返回什么?

操作系统是如何从虚拟地址映射到物理地址的?这些问题只是出于好奇,我想要一些关于现代操作系统的好的和深刻的见解,早期的操作系统是怎样的?我只对C/c++有专门的了解,因为我对其他语言知之甚少。

物理地址出现在硬件中,而不是软件中。操作系统内核中可能出现/偶尔出现的异常。物理的意思是系统总线和RAM芯片看到的地址。

物理地址不仅对软件无用,而且可能是一个安全问题。如果能够在不进行地址转换的情况下访问任何物理内存,并且知道其他进程的地址,就可以不受约束地访问机器。

也就是说,较小的机器或嵌入式机器可能没有虚拟内存,一些较旧的操作系统确实允许共享库指定它们的最终物理内存位置。这样的策略会损害安全性,而且已经过时了。

在应用程序级别(例如Linux应用程序进程),只存在虚拟地址。局部变量位于堆栈上(或寄存器中)。堆栈按调用帧组织。编译器在当前调用帧内生成局部变量的偏移量,通常是相对于堆栈指针或帧指针寄存器的偏移量(因此局部变量的地址,例如在递归函数中,只有在运行时才知道)。

尝试一步一步地在gdb调试器中执行递归函数,并显示一些局部变量的地址以了解更多信息。再试试gdbbt命令

类型
cat /proc/self/maps

了解执行cat命令的进程的地址空间(和虚拟内存映射)。

在内核中,从虚拟地址到物理RAM的映射是由实现分页和驱动MMU的代码完成的。一些系统调用(特别是mmap(2)和其他)可以改变进程的地址空间。

一些早期的计算机(例如1950年代或1960年代早期的计算机,如CAB 500或IBM 1130或IBM 1620)没有任何MMU,甚至最初的Intel 8086也没有任何内存保护。在当时(1960-s), C还不存在。在没有MMU的处理器上,您没有虚拟地址(只有物理地址,包括在洗衣机制造商的嵌入式C代码中)。有些机器可以通过物理开关保护对内存库的写入。今天,一些低端的廉价处理器(洗衣机里的那些)没有任何MMU。大多数便宜的微控制器没有任何MMU。通常(但并非总是),程序在某些ROM中,因此不能被有bug的代码覆盖。