C 64位AMD64模式下的分段故障

C 64位AMD64模式下的分段故障,c,segmentation-fault,64-bit,C,Segmentation Fault,64 Bit,我试图理解以下悖论: 我正在64位Linux上运行一个程序。所以程序在64位模式下运行(AMD64长模式的子模式),对吗? 但是这种模式没有分段,它只有分页。那么为什么下面的代码会产生分段错误呢 int main() { int* ptr = (int*)0xABCDABCDABCD; *ptr = 10; return 0; } 它被称为分段错误,与底层分页技术无关。这意味着(通常)你试图在你允许的范围(你的段)之外访问内存,它可以被称为block、chunk、section、m

我试图理解以下悖论:

我正在64位Linux上运行一个程序。所以程序在64位模式下运行(AMD64长模式的子模式),对吗? 但是这种模式没有分段,它只有分页。那么为什么下面的代码会产生分段错误呢

int main() {
  int* ptr = (int*)0xABCDABCDABCD;
  *ptr = 10;
  return 0;
}
它被称为分段错误,与底层分页技术无关。这意味着(通常)你试图在你允许的范围(你的段)之外访问内存,它可以被称为block、chunk、section、memlim、xyzy、plugh或任何术语

这与Java中出现空指针异常时非常相似,尽管该语言中没有“指针”:


在UNIX(SIGSEGV)中显示它的信号早在Intel给我们提供原始x86芯片的分段体系结构之前就已经存在了。

那么这是一个页面错误?但是页面错误会导致操作系统将页面加载到物理内存…@matheuscscp,同样,分页是底层技术,甚至可能不存在(但可能是针对后面的x86芯片)。操作系统很可能会出现页面错误,然后尝试引入页面,当它发现您的进程地址空间没有这样的页面可加载时,它可能会出现错误。例如,操作系统给你4M的地址空间,你试图写上面的东西:操作系统页面错误,发现它超出了你的范围,并在任何(真正)糟糕的事情发生之前阻止你。或者在虚拟地址空间中的3G线上方写入操作系统内存,并且该内存具有写保护。以此类推……好吧,但由于每个进程都有自己完整的64位虚拟寻址空间,因此系统如何确切地知道虚拟地址0xabcdcdabcd在边界之外?这是因为页面表中没有虚拟地址0xabcdabcd的页面条目吗?@matheuscscp:很可能是的。每个进程可能都有完整范围的虚拟地址,但这并不意味着它们已经将物理内存映射到每个地址后面。请参阅示例。此地址可能位于标记为只读的页面中。因此,试图通过:*ptr=10;将引发故障,通常为seg故障。