AMD64 準拠のアーキテクチャでは、アドレスは逆参照される前に正規の形式である必要があります。
64 ビット モードでは、アドレス ビット 63 からマイクロアーキテクチャによって実装された最上位ビットまでがすべて 1 またはすべて 0 に設定されている場合、アドレスは標準形式であると見なされます。
現在、現在のオペレーティング システムとアーキテクチャで実装されている最も重要なビットは 47 番目のビットです。これにより、48 ビットのアドレス空間が残ります。
特にASLRが有効になっている場合、ユーザー プログラムは 47 番目のビットが設定されたアドレスを受信することを期待できます。
ポインターのタグ付けなどの最適化が使用され、上位ビットが情報を格納するために使用される場合、プログラムは、アドレスを逆参照する前に、47 番目のビットが何であれ、48 番目から 63 番目のビットが設定されていることを確認する必要があります。
ただし、次のコードを検討してください。
int main()
{
int* intArray = new int[100];
int* it = intArray;
// Fill the array with any value.
for (int i = 0; i < 100; i++)
{
*it = 20;
it++;
}
delete [] intArray;
return 0;
}
ここで、次のように考えてintArray
ください。
0000 0000 0000 0000 0 111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1100
に設定it
して一度intArray
増やし、 を考慮すると、次のようになります。it
sizeof(int) == 4
0000 0000 0000 0000 1 000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
47 番目のビットは太字です。ここで何が起こるかというと、ポインター演算によって取得された 2 番目のポインターは、正規の形式ではないため無効です。正しいアドレスは次のとおりです。
1111 1111 1111 1111 1 000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
プログラムはこれにどのように対処しますか? アドレス範囲が 47 ビット目まで変化しないメモリが割り当てられないという OS の保証はありますか?