结论:x86-64 的 canonical 地址规范只使用低 48 位(4 级页表可寻址 256TB),高 16 位必须是第 47 位的符号扩展,否则 CPU 抛异常。这是硬件在寻址能力与实现成本间的折中:48 位已远超实际需求,完整 64 位翻译需要更多级页表、更多晶体管和更慢的 TLB。

展开:成本账:每级页表索引 9 位(512 项 × 8 字节 = 4KB 一页),4 级覆盖 12 + 9×4 = 48 位;支持 64 位需要 6 级页表,地址翻译的内存访问从 4 次增到 6 次,页表占用也膨胀,而当时(乃至现在)几乎没有机器装 256TB 内存。演进:Intel 的 5 级页表(LA57)已把虚拟地址扩到 57 位(128PB),供巨型内存机器和需要大虚拟地址空间的场景(如内存数据库)选用,Linux 4.14+ 支持但默认关。对开发者的实际影响:1)canonical 规则解释了 Linux 进程地址空间的布局——用户态 0x0000...0x00007fff...(128TB),内核态在高位 0xffff... 起,中间是巨大空洞;2)利用高位存元数据的指针标记技巧(tagged pointer)必须屏蔽高位后再解引用,ARM64 的 TBI 则硬件忽略高 8 位。易错点:48 位是虚拟地址;物理地址位数由 CPU 的 MAXPHYADDR 决定(常见 39–52 位),两者独立。

追问方向:页表层级与大页如何跳过中间级、ASLR 在 48 位空间里的熵有多少。