这样得到的两个地址都是虚拟地址(不是物理地址)。虽然虚拟地址是48位的但是储存这个地址的指针和加载这个地址的寄存器都是64位的,简单来说就是逻辑上只使用48位但是实际储存的时候是将一个虚拟地址当成64位来看,这样多余的16位(bit 63-48)实际上是不表示地址的。x86_64规定了一个合法的虚拟地址中这些多出来的位必须和第47位一致,所以就将地址空间分出了两个部分:0-0x00007FFFFFFFFFFF(bit 63-48都为0)以及从0xFFFF800000000000-0xFFFFFFFFFFFFFFFF(bit 63-48都为1)。Linux将处在地址空间低端分的第一部分分给用户,处在高端的第二部分作为内核自己的空间。所以你在用户态取一个变量的地址和在内核态取一个变量的地址就会有这样的差别,他们分别落在了地址空间中的两个区域当中。如果想要获得对应的物理地址,对于一个内核空间的虚拟地址(就是你提到的第二个)可以直接在内核态中用宏,如果是一个用户空间的虚拟地址 (就是你提到的第一个)就只能通过对用户进程的page table做一次page table walk得到了。
标签:0x00,寄存器,要用