it-swarm-ja.com

64ビットマシンで4ビット、8ビット、16ビット、または32ビットサイズのポインターを使用できますか?

符号なし64ビット整数の最大サイズ について大まかな計算を行いました。これは次のとおりです。

_18,446,744,073,709,551,615
q5 q4  t   b   m   t   h
_

AWSのハードウェア仕様 を最大のマシンで見ると、最大_3,904GB_になります。これは次のとおりです。

_3,904,000,000,000,000,000 bytes
5 q4  t   b   m   t   h
_

私にとって、それは ポインタは64ビット整数として格納されます を意味します。私は記憶とポインタについて考えるのは初めてですが、それを明確にしたかっただけです。

まだ少し混乱しています。 ポインタ は「プログラミング言語構造」です。したがって、技術的には、64ビットマシンでも、使用しているのが 〜40億 整数(32ビットの最大整数サイズ)未満の場合、なぜそれを使用できないのか疑問に思います。ポインタは32ビットです。そうすれば、スペースがなくなるまでポインターは32ビットになり、その後64ビットポインターの使用を開始できます。そうすれば、オブジェクトを増やすためのスペースが少し増えます。

それでも混乱しています。ポインタはメモリ内のアドレスの場所を保持します。 「アドレス」は64ビットだと書いてあります。したがって、64ビットメモリ内の32ビットチャンクを指す32ビットポインタがある場合、それがどのように見えるか、または意味するかはわかりません。それはあなたがしなければならないことを意味しているようです オフセット (私はそれをあまりよく理解していませんが)。

C、アセンブリ、またはJavaScriptで、32ビットポインタを64ビットアドレス空間に格納する方法を示すことができるかどうか疑問に思います。 Cが自動的に処理する場合、Assemblyはそれをどのように処理しますか。


上記のような大容量メモリを使用する方法を知りたいのですが、最大値に達するまで32ビットポインタを保存してから64ビットポインタを使用します。正確にどのようになるかわかりません。私がどう考えているかを説明する図を描いてみます。

_  | The bars and . are like a ruler and mark the bit positions.
  - Each row under a number (1, 2, 3, ...) means a memory address.
  ⬚ Means no data in memory address.
  ⬒ Means data of type 1 in memory address.
  ■ Means data of type 2 in memory address.
  ● Means a bit of integer pointer is plugged into memory address slot.
  ◌ Means no bit of integer pointer is plugged into memory address slot.
                                                                                                                                 |
                                                                 |                                                               |
                                 |                               |                               |                               |
                 |               |               |               |               |               |               |               |
         |       |       |       |       |       |       |       |       |       |       |       |       |       |       |       |
   . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |

1. Empty 64-bit memory.
   ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌
   ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚
   ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ...
   ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ⬚ ...
   ...
   ...

2. 64-bit memory filled with 32-bit pieces of data (type 1 ⬒, type 2 ■).
   ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌
   ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■
   ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ...
   ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ...
   ...
   ...

3. 64-bit memory filled with 64-bit pieces of data.
   ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌
   ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■
   ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ...
   ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ...
   ...
   ...

4. 64-bit memory filled with 4-bit pieces of data.
   ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌
   ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒
   ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ...
   ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ...
   ...
   ...

5. 64-bit memory filled with 32-bit pieces of data, with second 32-bits accessed by a 32-bit pointer.
   ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ●
   ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ 
   ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ...
   ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ... 
   ...
   ...

6. 64-bit memory filled with 64-bit pieces of data, with second 64-bits accessed by a 64-bit pointer.
   ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌
   ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■
   ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● ...
   ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ...
   ...
   ...

7. 64-bit memory filled with 4-bit pieces of data, with second piece of data accessed by a pointer.
   ◌ ◌ ◌ ◌ ● ● ● ● ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌
   ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒
   ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ...
   ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ⬒ ⬒ ...
   ...
   ...

8. 64-bit memory filled with 8-bit pieces of data, with second piece of data accessed by a pointer.
   ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ● ● ● ● ● ● ● ● ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌
   ■ ■ ■ ■ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ 
   ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ◌ ...
   ■ ■ ■ ■ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ■ ■ ■ ■ ■ ■ ■ ■ ⬒ ⬒ ⬒ ⬒ ⬒ ⬒ ...
   ...
   ...
_

私が想像しているのは、整数はロック(メモリアドレス)のキーのようなものだということです。空の鍵穴は、(1)の64◌の列のように見えます。 64ビットアドレスの完全なキーホールは、(6)の64●の行のように見えます。 64ビットのメモリアドレス空間に2ビットキーを指定すると、(5)のようになります。したがって、64ビット長(64◌長)のキーホールを完全に埋めることはできず、後半(この場合)のみを埋めます。そのため、住所と一致しないようです。しかし、私は後半に32ビットのデータを指摘しようとしています!アドレスを一致させるには、(6)のように、64ビット行全体の鍵穴を埋める必要があるようです。ここで私の理解が台無しになっているのではないかと思います。どこにいるのか教えてください。

それが明確でない場合、チャートの最初の数字1〜4は​​、メモリにあるデータを示しています(1は空のメモリです)。 2番目の数字5〜8は、ポインタを使用してデータにaccessしようとしていることを示しています(行の黒い円●はメモリアドレスロックへのポインタ/キーです)。

最後に、最後の問題が1つあります。それをさらに進めて、さらに小さなチャンクでデータを保存できるかどうか疑問に思います。 (7)のように4ビットのデータを格納するなど。これは、ポインタ/アドレスシステムがどのように機能するかをもう少し詳しく説明するためのものです。 4ビットポインタが4ビットのメモリチャンクを指すことができるかどうかはわかりません。これは、アライメント要件のために、一度に少なくとも8ビットをフェッチすることになるようです。しかし、それは大丈夫です。 nビットポインタを使用して64ビットメモリ空間のnビットのデータにアクセスできるかどうかを確認したいだけです。

もしそうなら、Cまたはアセンブリ、あるいはJavaScriptのいずれかでそれがどのように見えるかはまた機能します。

これを知りたいので、64ビットメモリにデータを格納する方法と、「メモリアドレスは64ビット」の場合にポインタを使用して何ができるかを知りたいと思います。つまり、memory.get(a32BitPointer)を実行して、32ビットで整列されたメモリスロットから32ビットのデータを返すようにできれば。 (または同等に、4、8、16などのビットデータまたはサイズのポインター)。

1
user39251

ポインタ に指差す含む絶対アドレス。

ポインタを使用する前に値を追加する必要がある場合、実際のポインタではなく、オフセットがあります。

Cでは、voidポインターは関数ポインターにすることができます。あなたはそれを通して関数を呼び出すことができます。 CPUが64ビットモードの場合、これを機能させるには、64ビットすべてが必要です。

CPUが64のアドレスラインをサポートしている場合(物理的には少ない場合があります)、2 ^ 64のアドレス空間があります。これは0x1 0000 0000 0000 0000です。範囲は0x0000 0000 0000 0000から0xFFFF FFFF FFFF FFFFです。

ポインタをCPU命令で使用できるようにし、実際の意味を見つけるために追加のCPU命令を必要としない場合(ネイティブCPUコードはポインタを直接処理できます)、CPUのアドレス空間と同じ幅である必要があります。

CPUには必要なアドレスを取得するために追加する必要があるため、オフセットは遅くなりますが、CPUにはそれを行うネイティブ命令もあります。

私はx86-64ISAの専門家ではありませんが、32ビット値を64ビット値として扱い、最初の32ビットを0と見なすCPU命令がある可能性があります。CPUは依然として実際の値を内部的に「拡張」する必要があります。 64ビットまでの値。

X86およびx86-64では、確かに8、16、32、および64ビットを使用できますオフセット(x86/x86 CPU命令は4ビット値だけでは機能しません)

3
LawrenceC

まず、3904GBのメモリはアドレス指定に42ビットしか必要としません。計算したものではなく、_3 904 000 000 000_バイトのみで構成されます。 PowerShellですばやく確認できます

_PS C:\> [math]::Log(3904GB, 2) # GB base 2, or GiB
41.9307373375629
PS C:\> [math]::Log(3904e9, 2) # GB base 10
41.8280901915491
_

したがって、技術的には、64ビットマシンでも、使用している整数が40億未満(最大整数サイズは32ビット)の場合、ポインタを32ビットにすることができないのはなぜかと思います。そうすれば、スペースがなくなるまでポインターは32ビットになり、その後64ビットポインターの使用を開始できます。そうすれば、オブジェクトを増やすためのスペースが少し増えます。

x32 ABI64ビットx86 ABI で、32ビットポインタを使用します。プロセスには32ビットのアドレス空間しかありません。つまり、4GBを超えるメモリを使用することはできませんが(ほとんどのユーザーアプリケーションでは問題ありません)、より大きく広いレジスタ空間を利用できます。グローバルメモリスペースはハードウェアで固定されているため、64ビットのままです。したがって、32ビットポインタは、直接ポインタではなく、プロセスのベースアドレスへのオフセットとして使用されます。実装は単純にこのようなものです

_void* getRealPointer(uintptr_t base_addr, uint32_t ptr)
{
    // value stored in pointer is the offset/distance from base
    return (void*)(base_addr + ptr);
}
_

この手法は、Sparcなどの他の多くの64ビットRISCアーキテクチャでも一般的です( Linux on sparc64アーキテクチャがユーザースペースで32ビットポインターを使用し、カーネルスペースで64ビットポインターを使用するのはなぜですか? )、 MIPSまたはPowerPC、64ビットへの移行時にx86やARMなどのレジスタの数が増えなかったため、64ビットのプロセスが64ビットのプロセスよりも高速である可能性があります。ビット計算または2/3/4GBを超えるRAM

G5などの64ビットプロセッサでは、Debian PPCは32ビットのユーザースペースを持つ64ビットカーネルを使用します。これは、64ビットのPowerPCプロセッサには「32ビットモード」がないためです。 「Intel64/AMD64アーキテクチャのように。したがって、64ビットの数学関数を必要としない64ビットのPowerPCプログラムは、64ビットのポインタと長い整数が2倍のメモリを消費するため、32ビットのプログラムよりも実行速度が多少遅くなります。 CPUキャッシュが高速であるため、より頻繁なメモリアクセスが必要になります。

PowerPC上のLinux

それでも、32ビットポインタ_until you run out of space then start using 64-bit pointers_だけを使用することはできません。それは意味がありません。タイプは常に固定サイズです。ポインタの32ビットのみにスペースを予約した場合、64ビットポインタを使用する必要があるとどうなりますか?高い部分はどこに保管しますか?


したがって、64ビットメモリ内の32ビットチャンクを指す32ビットポインタがある場合、それがどのように見えるか、または意味するかはわかりません。

それは ワードアドレス可能なメモリ と呼ばれます。各バイトを指す代わりに、各値が単に異なるWordを指すようになりました。

一意のIDで識別される一連の線形セルで構成されるメモリを想像する方が簡単です。これらのIDは、通常「アドレス」と呼ばれるものであり、ポインターに格納されるものです。最新のシステム(つまり、バイトアドレス可能なメモリ)では、セルサイズは通常1バイトです。ただし、 nisysやPDPなどの多くの古いシステムはWordアドレス可能メモリを使用します セル​​にはWordが含まれています(これらのアーキテクチャの場合は36ビット長)。したがって、これらのシステムでは、アドレス指定するバイトの位置を格納するためにさらにビットが必要になるため、_char*_は_int*_よりも大きくなります。

私はあなたのチャートを完全には理解していませんが、それは明らかに私たちが対処できる総メモリを減らすので、人々がそのように各ビットに対処する必要はめったにありません。公平を期すために、ビットアドレス指定可能なメモリを備えたアーキテクチャがいくつか存在します。主に組み込みシステムです。 CPUに32ビットアドレスを与えるときに64ビット値の下位32ビットが必要なように見えるが、そのようには機能しない場合。それぞれの半分に対処するには、そのようなビット数の半分ではなく、もう1つの最上位ビットが必要になります。原則は単純です。同じ量のメモリよりも大きなセルサイズを使用すると、必要なセルが少なくなります。つまり、IDに必要なビットが少なくなります。およびその逆。ハードウェアレベルでは、セルサイズは通常固定されています。

以下は、メモリの最初の16バイトの例です。

_╔══════╤══════╤══════╤══════╤══════╤══════╤══════╤══════╤══════╤══════╤══════╤══════╤══════╤══════╤══════╤══════╗
║ 0000 │ 0001 │ 0010 │ 0011 │ 0100 │ 0101 │ 0110 │ 0111 │ 1000 │ 1001 │ 1010 │ 1011 │ 1100 │ 1101 │ 1110 │ 1111 ║
╠══════╪══════╪══════╪══════╪══════╪══════╪══════╪══════╪══════╪══════╪══════╪══════╪══════╪══════╪══════╪══════╣
║ b0   │ b1   │ b2   │ b3   │ b4   │ b5   │ b6   │ b7   │ b8   │ b9   │ b10  │ b11  │ b12  │ b13  │ b14  │ b15  ║
╟──────┴──────┼──────┴──────┼──────┴──────┼──────┴──────┼──────┴──────┼──────┴──────┼──────┴──────┼──────┴──────╢
║ w0 000      │ w1 001      │ w2 010      │ w3 011      │ w4 100      │ w5 101      │ w6 110      │ w7 111      ║
╟─────────────┴─────────────┼─────────────┴─────────────┼─────────────┴─────────────┼─────────────┴─────────────╢
║ dw0 00                    │ dw1 01                    │ dw2 10                    │ dw3 11                    ║
╟───────────────────────────┴───────────────────────────┼───────────────────────────┴───────────────────────────╢
║ o0                                                    │ o1                                                    ║
╚═══════════════════════════════════════════════════════╧═══════════════════════════════════════════════════════╝
_

この回答 のイラストもご覧いただけます。

各2バイトワードをアドレス指定すると、N番目のワードのバイトアドレスはN * 2になります。実際のオフセットをoffset*sizeof(chunk)として計算できる他のチャンクサイズと同じです。その結果、4バイトにアラインされたアドレスの下位2ビットは常にゼロになります。 Wordアドレス可能ポインタを使用しない場合、それらの下位ビット データの格納に使用できます これは タグ付きポインタ と呼ばれます

64ビットJVMは、この手法を compressed Oops で使用します。 JVMの圧縮されたOopsの背後にあるトリック を参照してくださいJavaのオブジェクトは常に8バイトに整列されるため、32ビットアドレスで8 * 4 = 32GBのメモリをアドレス指定できます。

Javaヒープ内のマネージポインターは、8バイトのアドレス境界に整列されたオブジェクトを指します。圧縮されたoopsは、マネージポインター(JVMソフトウェアのすべてではありませんが多くの場所)を32ビットオブジェクトとして表します。 64ビットからのオフセットJavaヒープベースアドレス。バイトオフセットではなくオブジェクトオフセットであるため、最大40億個のオブジェクト(バイトではない)またはヒープのアドレス指定に使用できます。最大約32ギガバイトのサイズ。これらを使用するには、8倍にスケーリングし、Javaヒープベースアドレスに追加して、参照するオブジェクトを見つける必要があります。使用するオブジェクトサイズ圧縮されたoopsは、ILP32モードのものと同等です。

https://docs.Oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html#compressedOop

最近、GoogleはV8レンダリングエンジンにも同じ手法を適用し、 64ビットV8では32ビットポインタ を使用して、メモリフットプリントを最大35%削減します。

ほとんどのRISCアーキテクチャの分岐およびロード/ストア命令は、Wordアドレスも直接の部分に格納します。これは、これらの常にゼロのビットを節約する貴重なスペースを無駄にする意味がないためです。例 MIPS分岐およびジャンプ命令 :JAL、J、BEQ、BLEZ、BGTZ .. ..

1
phuclv