0

私は現在、JS で Logisim CPU 用の C++ コンパイラに取り組んでおり、変数に問題があります。

データ/値を格納するための RAM 内のスペースを定義し、データ スペースへのアドレスを格納するためのスペースを定義しました。最後の変数へのポインタを持つレジスタ nx と、最後の「データストレージ」RAM へのポインタを持つレジスタ mx があります。しかし、それらにアクセスする方法がわかりません。たとえば、次のとおりです。

変更された C++ コード:

int *pointer_test;
int test;
test = 123;
pointer_test = &test;
*pointer_test = 25;

プリアセンブラー:

//Allocate new variable       <---  int *pointer_test;
add nx, 1
//Set the pointer pointing to zero
sram nx, 0


//Allocate another variable   <---  int test;
add nx, 1
//Allocate new storage for the variable
add mx, 1

//Let the variable point to the data <--- test = 123;
sram nx, mx
sram mx, 123

今すぐ実装するにはどうすればよいですか:

pointer_test = &test; 

&test の値のみが nx に保存されています。これは、宣言された最後の変数であるためですが、変数/ポインター「pointer_test」のアドレスではありません ...

4

1 に答える 1

4

おそらく、過去 20 年間の他のすべての C コンパイラと同様に、スタック ベースのアセンブリを書きたいと思うでしょう。つまり、RAM にはスタックと呼ばれるデータ領域があり、これは FIFO キューであり、成長します。スタックには、常に少なくとも 1 つのレジスタ (スタック ポインター) が含まれます。スタック ポインターは、次に移動するスタック内の現在の場所を指します。したがって、スタックに何かを追加するには、スタック ポインターが指す場所にそれを配置し、スタック ポインターからそのサイズを減算します。

C 由来のアセンブリで最も頻繁に使用されるもう 1 つのレジスタは、ベース ポインタです。ベース ポインターは、現在のフレームの先頭を指します。フレームは、C のスコープと大まかに比較できます。したがって、次のコードがある場合:

int a;
{
  int b;
}

そして、一番上のスタックは 0x9999 にあり、次にa0x9995 (4 バイトの int を想定) になり、スタック ポインターは 0x9991 を指し、ベース ポインターは 0x9999 のままになります。新しいスコープに入ると、ベース ポインターがスタック ポインターに移動され、B が 0x9991 に置かれます。次に、スコープを終了すると、スタック ポインターがベース ポインターに設定され、下位のスコープ内の変数が効果的に消去されます。

あなたがプログラミングしているアーキテクチャについては聞いたことがありませんが、任意の 2 つのレジスタで機能することは知っていますが、x86 などの一部のアーキテクチャには、特定の stak レジスタ ( ebp32espビットおよびreb64rspビット) があります。

しかし、質問にもう少し答えると、各変数がスタックへのオフセットを知るのはコンパイラの仕事なので、(疑似コード)のようなことができます:

base_pointer - 5 (Offset for pointer_test) = base_pointer - 4 (offset for test)
于 2012-10-21T14:27:09.037 に答える