Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否可以访问物理地址0?_C++_C_Assembly_Operating System_X86 - Fatal编程技术网

C++ 是否可以访问物理地址0?

C++ 是否可以访问物理地址0?,c++,c,assembly,operating-system,x86,C++,C,Assembly,Operating System,X86,在C/C++中,不允许访问地址0处的数据 但是,物理内存从0开始编号。在DOS时代,中断向量表位于物理地址0。第一个中断向量是零除异常的处理程序 我的问题是: 在什么情况下允许访问物理地址0?通常,in由管理 独立的C(或C++)实现当然可以允许您以特定于实现的方式取消引用(void*)0。但是要小心 P> C++和C++标准对空指针非常小心(C++ 11添加了 NulLPTR < /Cord>关键字有几个好的原因)。 允许C编译器(至少是托管实现)假设成功取消引用后指针不为null。中的一些

在C/C++中,不允许访问地址0处的数据

但是,物理内存从0开始编号。在DOS时代,中断向量表位于物理地址0。第一个中断向量是零除异常的处理程序

我的问题是:

在什么情况下允许访问物理地址0?

通常,in由管理

独立的C(或C++)实现当然可以允许您以特定于实现的方式取消引用
(void*)0
。但是要小心

<> P> C++和C++标准对空指针非常小心(C++ 11添加了 NulLPTR < /Cord>关键字有几个好的原因)。 允许C编译器(至少是托管实现)假设成功取消引用后指针不为null。中的一些优化正在这样做

大多数托管C或C++实现都有一个空指针,它是一个全零位字,但这不是标准所要求的(但是,它非常普遍;它帮助编译器和LIBC)。 然而,实际上,许多软件都假设NULL由所有零位表示(理论上这是一个错误)

我知道没有一个C实现
NULL
不是全部零位,但这不是必需的。然而,编写这样一个编译器将是一件令人头痛的事

在某些操作系统上,应用程序可以更改其地址空间,例如使用On或Linux

如果您真的愿意,您可以在C中访问地址0,但您真的不应该这样做

在C/C++中,不允许访问地址0

是的,你可以,只要有可寻址内存。在大多数平台上,不会有

在什么情况下允许访问物理地址0


如果物理地址映射到虚拟内存中,则可以访问它。如果存在任何敏感信息,那么操作系统可能不允许在用户代码中使用这些信息。在内核中,只是设置页表以包含该地址。

< P>,C或C++中没有指定允许您为指针指定特定物理地址的规范。因此,您关于“如何访问地址0”的问题可以转换为“如何将地址0分配给指针”的问题,但在形式上没有答案。在C/C++中,您无法将特定地址分配给指针

但您可以通过整数到指针的转换获得这种效果:-

uintptr_t null_address = 0;
void *ptr = (void *) null_address;

要访问物理地址0,这取决于您正在使用的平台。 该语言不知道底层寻址模型,它依赖于操作系统

  • 在裸机环境中,如果启用了分页,则对页表拥有完全控制权;如果未启用分页,则仅取消引用零
  • 在某些Unix和Linux变体上,您可以执行
    mmap
    ,也可以打开/dev/mem以获取逻辑地址非零但物理地址为零的非空指针,它可能需要一些访问权限
  • 我不确定是否在Windows上

另外,其他答案似乎在语言水平指针和物理地址上有点混乱。

你的问题有点混乱。您询问是否可以“访问零物理地址”。在现代分页操作系统中,应用程序根本无法指定物理地址。物理地址只能通过内核模式访问

在虚拟内存系统中,通常不将虚拟内存的第一页映射到进程地址空间。因此,访问虚拟地址零将触发访问冲突

在这样的系统中,应用程序通常可以通过系统服务将第一页映射到进程访问空间。即使默认情况下页面不存在,应用程序也可以添加该页面


答案是可以在内核模式下访问物理内存地址零,如果应用程序将该页映射到内存(操作系统允许),则可以访问虚拟内存地址零。

C标准不要求平台提供对任何特定物理内存位置的访问,零或其他。虽然在许多嵌入式平台上,(char*)0x1234访问物理位置0x1234是很常见的,但C标准中没有要求这样做

C标准也不要求平台做任何事情,特别是在试图访问空指针时。因此,如果编译器编写器希望将空指针解引用视为对物理位置零的访问,则这种行为是一致的


对地址零的访问有意义且有用的编译器通常会将空指针访问解释为对位置零的访问。唯一的问题是在平台上,对位置0的访问是有用的,但编译器编写人员不知道这一点。这种情况通常只能通过检查编译器的文档来处理,以找到迫使编译器像对待任何其他地址一样对待空指针的方法。

这两种语言的标准中都没有这样的限制。如果进程在不受保护的虚拟内存地址空间下运行,则它可以访问物理地址0。保护本身由操作系统使用MMU实现。所有这些都与C和C++无关,很可能是在OS保护的区域中;甚至可能是ROM的一部分。正如@SJuan76所指出的,这不是语言的限制,而是@barakmanos所说的实质性限制。地址0在我的嵌入式系统上有效。“任何旧线程都可以写入它。@MartinJames:就像我说的,如果进程在不受保护的虚拟内存地址空间下运行,它可以访问物理地址0。”。如果您只运行一个进程,而没有虚拟内存管理(就像许多嵌入式系统一样,有时甚至没有OS+多线程)