最後に、私のコンピューターの電磁リレーで、1命令より長いプログラムを実行できます。 現在では、8つのチーム用のROM、ALUを備えたプロセッサ、8つの8ビットレジスタ(そのうちの1つはPC)を備えています。
合計で、プロセッサは、算術論理演算(ALU)、レジスタへの数値のロード(MOVI)、レジスタ間の転送(MOV)、作業の停止(HALT)、メモリの処理(LDST)の5つの命令グループをサポートします。 しかし、微妙な違いがあります...
これら5つのグループに加えて、コードは説明の NOP操作用に予約されていますが、プロセッサによってデコードされることはありません。 実際には、すべての未使用の組み合わせがNOPとして機能します。
フォワードコマンド
遷移さえない場合、そのようなコマンドのセットで何ができるでしょうか? PCは他のレジスタ(A、B、C、D、M、S、L)と同等のレジスタファイルに含まれているため、PCを使用したすべての操作は他のレジスタと同じ方法で実行されます。 次に、整数をPCにダウンロードすると、アドレスに移行します。
MOVI命令の2つのフィールドは、レジスタと8ビットの直接オペランドです。 私が持っているコマンドはすべて、メモリからの読み込み、デコード、およびマシンコードでのプログラミングを簡素化するために16ビットです。 MOVI命令コードは次のように
1cccLddd iiiiiiii
フィールドiはレジスタに書き込まれる値、フィールドdはどのレジスタが変化するか、1-このビットにより、これはまさにMOVI命令であることがわかります。
残りの4ビットがあります。 それらのうち3つ(c)は、命令が実行される条件下で与えられます。 合計7つの組み合わせが含まれます。遷移は常に、オン/オフゼロフラグ、キャリーフラグ、サインフラグによるものです。 8番目の組み合わせは使用されません。
最後の残りのビット(L)を使用すると、サブルーチン呼び出しコマンドを実装できます。 このビットが設定されている場合、命令は次の命令のアドレスをレジスタLに書き込みます。 これは、ARMおよびMIPSのように、プロシージャコールは次の命令のアドレスを特別なレジスタに書き込むだけの移行です。 手順から戻るには、この値をPCに再度コピーする必要があります。 したがって、個別のRETコマンドは必要ありません。
ただし、1つのレジスタを別のレジスタにコピーする命令が必要です-MOV。 実際、ALUを使用して(たとえば、ADD D、S、0またはOR D、S、Sとして)実装できますが、すぐには考えませんでした。 また、結果のソリューションにはプラスがあります。ALUモジュールのリレーは、算術演算と論理演算にのみ使用され、通常の転送中にフラグが劣化しないため、消耗が少なくなります。
コンピューター回路の設計に関連する1つの副作用を除いて、MOVチーム自体は目立たない。 その動作のアルゴリズムは次のとおりです。レシーバーレジスタをリセットし、ソースレジスタとレシーバーを同じバスに接続して、リレーがソースに既に接続されているレシーバーでもオンになるようにします。 このため、それ自体からレジスタへの転送コマンドはNOPのようには機能せず、レジスタをリセットするように機能します。
ALU
最も興味深いものはこのカテゴリに隠されています-すべての算術および論理演算ですが、ここではALUが演算のタイプの決定に直接関与しています。 入力には、オペレーションコード、2つのレジスタまたはレジスタ+イミディエート値、出力には1つのレジスタがあります。 これがMOVで発生するのを防ぐため、内部のALUには計算の結果が書き込まれるシャドウレジスタが含まれています。 したがって、算術論理コマンドのオペランドは、任意の組み合わせの任意のレジスタにすることができます。
コマンドの一般的な形式は次のとおりです。
01bbbddd ixxxryyy - ADD, ADC, SUB, SBC, AND, OR, XOR
01111ddd -xxxruu0 - NOT, SHR, ROR, RCR
ここで、dは出力レジスタのコード、x、yは入力レジスタのコード、bは二項演算のタイプ、uは単項演算のタイプです。 iフラグが設定されている場合、3つのyyyビットがコマンドの直接の第2オペランドとして使用されます。 したがって、小さな定数を追加/減算する方が便利です。
せん断操作はZ80のように機能し、i386のようには機能しません。1ビットだけシフトします。 循環シフト以外のすべてに対して加算を行うことができるため、左へのシフトはありません。 さて、左への循環シフトは2つの命令で行われます。
ADD A, A, A
ADC A, A, 0
ALUは、最後の操作の3つのフラグ-キャリー、ゼロ、サインを保存します。 さらに、ALUが次のコマンドを実行し、残りの命令を損なわない場合にのみ変更されます。 必要に応じて、関数からでもフラグを返すことができます。
フラグ値を取得するために大文字と小文字を上書きすることは必ずしも便利ではありません。 i386のようなCMPやTSTのようなコマンドを作成するには、ALU命令コードのビットrをリセットする必要があります。 その後、計算の結果はシャドウレジスタにのみ残り(フラグをカウントできるように)、通常のレジスタは変更されません。
ファイヤーキャッチと
HALT-コンピューターを停止するコマンド。 クロックジェネレーターは動作を停止し、すべてがフリーズします。 [開始]ボタンをクリックして、次のコマンドの操作を続行できます。
メモリを操作する
メモリを操作するための命令もいくつかあります(レジスタ内のアドレスと直接アドレスへの読み取り/書き込み)。 しかし、現在はメモリからROMが8ワードしかないため、これらの命令からはまだほとんど意味がありません。
ROM
ROMは、設計上、8ビットバス全体から64アドレスを占有します。 各アドレスについて、コマンドをフェッチするときに16ビット、データをフェッチするときにこのコマンドの下位8ビットを読み取ることができます。
ROMセルは2つのDIPスイッチで構成されています。 そのため、プログラムを簡単に入力したり、セルに「書き込まれた」内容を確認したりできます。 各命令の反対側には、プログラムの進行状況を監視するLEDがあります。
「予期せず」問題は、電流が両方向にキーを通過できることを考慮するのを忘れたときに発生しました。 したがって、1つのセルを選択すると、他の複数のセルが同時にバスに接続できます。
すでにダイオードの場所を提供している新しいボードのセットを注文する必要がありました。 確かに、ROM 128個の128個のSMDダイオードを8セルごとにはんだ付けする必要があるため、はんだ付けにかかる時間が長くなりました。
8つの指示に適合するものは何ですか?
これまで、フィボナッチ数を計算するためのプログラムのみを作成しました。
1000 0001 0000 0001 00: movi B, 1
0100 1010 0001 1000 01: add C, B, A
0001 1000 0001 0000 02: mov A, B
0001 1001 0010 0000 03: mov B, C
1000 0111 0000 0001 04: jmp 01
使用可能な8語のうち5語しか使用しなかったため、より複雑なプログラムを思いつくことができますが、興味深いアイデアはまだありません。
» githubのプロジェクトページ
» コマンドシステムの詳細な説明
» 説明の最初の部分
» 説明の2番目の部分
» 説明の3番目の部分