#include <stdio.h>
int main(void){
int *ptr;
printf("the value of ptr is %p",ptr);
}
これにより0x7fffbd8ce900
、わずか6バイトのが得られます。8バイト(64ビット)にする必要がありますか?
ポインタは64ビットですが、現在のプロセッサは実際には48ビットしかサポートしていないため、アドレスの上位2バイトは常に0000または(符号拡張のために)FFFFのいずれかになります。
将来、48ビットでは不十分な場合、新しいプロセッサは56ビットまたは64ビットの仮想アドレスのサポートを追加できます。既存のプログラムはすでに64ビットのポインタを使用しているため、追加のスペースを利用できるようになります。
これは、最初の2バイトがゼロであることを意味します(ちなみに、現在x86-64チップで保証されていますが、ポインターが初期化されていないため、この場合は何の意味もありません)。%p
他の数値タイプと同様に、先行ゼロを切り捨てることができます。%016p
ただし、そうではありません。これは正常に機能するはずです。
printf("the value of ptr is %016p", ptr);
6バイトのアドレスは単なる仮想アドレス(実際の物理アドレスのオフセット)であるためです。物理アーキテクチャ(たとえばX86)では、メモリは16ビットセグメントセレクタを変更せずに単一のインデックスレジスタでアドレス指定できる部分に分割されます。X86-CPUのリアルモードでは、セグメントは常に16ビット(2バイト)のセグメントセレクターを使用します。これは、プログラムの実行開始時(つまり、実際の実行プロセスの作成時)にオペレーティングシステムによって動的に決定されます。 )。
したがって、変数に48ビットアドレス0x7fffbd8ce900があり、プログラムにセグメントセレクタオフセット08afがあり、変数の実際のアドレスが(0x08af << 48)+ 0x7fffbd8ce900 = 0x08af7fffbd8ce900、つまり64ビットである場合。
さらに読むplsは次のようになります: x86メモリセグメンテーション