在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/c++有专门的了解,因为我对其他语言知之甚少。
物理地址出现在硬件中,而不是软件中。操作系统内核中可能出现/偶尔出现的异常。物理的意思是系统总线和RAM芯片看到的地址。
物理地址不仅对软件无用,而且可能是一个安全问题。如果能够在不进行地址转换的情况下访问任何物理内存,并且知道其他进程的地址,就可以不受约束地访问机器。
也就是说,较小的机器或嵌入式机器可能没有虚拟内存,一些较旧的操作系统确实允许共享库指定它们的最终物理内存位置。这样的策略会损害安全性,而且已经过时了。
在应用程序级别(例如Linux应用程序进程),只存在虚拟地址。局部变量位于堆栈上(或寄存器中)。堆栈按调用帧组织。编译器在当前调用帧内生成局部变量的偏移量,通常是相对于堆栈指针或帧指针寄存器的偏移量(因此局部变量的地址,例如在递归函数中,只有在运行时才知道)。
尝试一步一步地在gdb
调试器中执行递归函数,并显示一些局部变量的地址以了解更多信息。再试试gdb
的bt
命令
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的代码覆盖。
- 防止主数据类型C++的隐式转换
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 在C++中打印指向不同基元数据类型的指针的内存地址
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 如何计算数据类型的范围,例如int
- C++中数据类型修饰符的顺序
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- 特定数据类型的模板类
- 具有多个模板的模板函数,用于特定数据类型(如字符串)?
- 有没有办法提示用户使用哪种数据类型作为模板 c++
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 时间复杂度 当具有复合数据类型(如元组或对)时?
- 如何获取C++字符数据类型的地址
- 将复杂的非基元C++数据类型转换为 Erlang/Elixir 格式,以使用 NIF 导出方法
- 如何在不破坏现有应用程序的情况下更改 API 中 stl 容器的数据类型?
- wxWidgets 应用程序中的 SOCI 数据类型
- 如果应用程序仅针对 armv7 和 armv7 编译,则在 arm64 设备上运行时,它使用什么大小的数据类型
- 对字符串和基本数据类型应用大于或小于检查
- 在托管c#应用程序的非托管c++ Dll调用中,如何处理数据类型之间的冲突
- 在C/ c++或任何其他类似语言中,对变量或数据类型应用&符号时返回的地址类型