对于64位80x86;通常(见注1)只能使用48位的虚拟地址.为了在不 destruct 旧软件的情况下更容易地增加future 处理器中可以使用的位数,AMD决定64位虚拟地址中未使用的最高16位应该匹配.符合这一要求的地址被称为"规范地址",而不符合这一要求的地址被称为"非规范地址".正常情况下(见注2),任何访问非规范地址上的任何内容的try 都会导致异常(一般保护故障).
这提供了如下的虚拟地址空间:
0x0000000000000000 to 0x00007FFFFFFFFFFF = canonical (often "user space")
0x0000800000000000 to 0xFFFF7FFFFFFFFFFF = non-canonical hole
0xFFFF800000000000 to 0xFFFFFFFFFFFFFFFF = canonical (often "kernel space")
这使得很明显,在没有地址空间布局随机化的情况下,进程的初始线程堆栈(参见注释3)从略低于进程可以使用的最高地址的地址开始.
进程可以使用的最高地址和您看到的地址(0x7FFFFFFDFD0)之间的差异只有2030个字节;正如Fuz的注释所提到的那样,ELF AUX向量、命令行参数和环境变量等使用这些地址的东西在代码开始之前消耗了堆栈的一部分.
Note 1: Intel recently (about 2 years ago?) created an extension that (if supported by CPU and OS) makes 57 bits of a virtual address usable. In this case the "non-canonical hole" shrinks, and the highest virtual address a process can use would be increased to 0x00FFFFFFFFFFFFFF.个
Note 2: More recently (about 6 months ago?) Intel created an extension that (if supported by CPU and OS and enabled for a process) can make the unused higher bits of an address ignored by the CPU; so that software can pack other information into those bits (e.g. maybe a "data type") without doing explicit masking before use.个
Note 3: Because operating systems typically provide no isolation between threads (e.g. any thread can corrupt any other thread's stack or any other thread's "thread local data"); if you create more threads they can't use the same "top of stack" address.个