The Elements of Computing Systems を読んで勉強していますが、ある時点で立ち往生しています。次の 5 つの命令をスキップする章のサンプルは、ここにあります。
とにかく、私は仮想マシン (またはアセンブリ トランスレータへのバイト コード) を実装しようとしていますが、次の 5 つの命令を 1 点スキップすることで立ち往生しています。
アセンブリ表記については、こちらを参照してください。
目標は、特定のバイト コードをこのアセンブリ コードに変換するトランスレータを実装することです。
私が成功した例は、バイトコードです
push constant 5
これは次のように翻訳されます。
@5
D=A
@256
M=D
私が言ったように、Hack のアセンブリ言語は私が提供したリンクにありますが、基本的には次のとおりです。
@5 // Load constant 5 to Register A
D=A // Assign the value in Reg A to Reg D
@256// Load constant 256 to Register A
M=D // Store the value found in Register D to Memory Location[A]
さて、これはかなり簡単でした。定義により、メモリ位置 256 はスタックのトップです。そう
push constant 5
push constant 98
に翻訳されます:
@5
D=A
@256
M=D
@98
D=A
@257
M=D
これはすべて問題ありません..
また、もう 1 つ例を挙げたいと思います。
push constant 5
push constant 98
add
は次のように翻訳されます。
@5
D=A
@256
M=D
@98
D=A
@257
M=D
@257 // Here starts the translation for 'add' // Load top of stack to A
D=M // D = M[A]
@256 // Load top of stack to A
A=M // A = M[A]
D=D+A
@256
M=D
かなり明確だと思います。
ただし、バイトコードをどのように変換できるかわかりません
eq
アセンブリへ。eq の定義は次のとおりです。
コマンドのうち 3 つ (eq、gt、lt) はブール値を返します。VM は、true と false をそれぞれ -1 (マイナス 1、0xFFFF) と 0 (ゼロ、0x0000) として表します。
したがって、レジスタ A と D にそれぞれ 2 つの値をポップする必要がありますが、これは非常に簡単です。しかし、値をチェックして結果が true の場合は 1 をプッシュし、結果が false の場合は 0 をプッシュするアセンブリ コードを作成するにはどうすればよいでしょうか?
Hack Computer でサポートされているアセンブリ コードは次のとおりです。
私は次のようなことができます:
push constant 5
push constant 6
sub
スタックにプッシュされた 2 つの値が等しい場合は値 0 を保持し、そうでない場合は !0 を保持しますが、それはどのように役立ちますか? D&AまたはD&Mを使用してみましたが、どちらもあまり役に立ちませんでした..
条件付きジャンプを導入することもできますが、ジャンプ先の命令をどのように知る必要があるのでしょうか? Hack Assembly コードには、「次の 5 つの命令をスキップする」などのようなものはありません。
[Spektre による編集] 私が見たターゲット プラットフォームの概要
- 16 ビット フォン ノイマン アーキテクチャ (アドレスは 15 ビット、16 ビット ワード アクセス)
- データメモリ 32KW (読み取り/書き込み)
- 命令 (プログラム) メモリ 32KW (読み取り専用)
- ネイティブ 16 ビット レジスタ A、D
- 0x0000 ~ 0x000F のデータ メモリにマッピングされた汎用 16 ビット レジスタ R0 ~ R15
- これらは、次の目的にも使用される可能性が最も高いです。
SP(R0),LCL(R1),ARG(R2),This(R3),That(R4)
- 画面は 0x4000-0x5FFF (512x256 B/W ピクセル 8KW) のデータ メモリにマップされます。
- キーボードは 0x6000 のデータ メモリにマップされます (最後にキーを押した場合は ASCII コード?)