Implementing a One Address CPU in Logisimのアセンブリ言語仕様

Implementing a One Address CPU in Logisim では、アセンブリ言語仕様を作って、それをJavaで作ったアセンブラープログラムで、マシン語に変換しています。このアセンブリ言語を理解するために、ブログでメモします。

2.3アセンブラー・ディレクティブ(Assembler Directives)

  • .textディレクティブ

これ以下のテキストがアセンブリ命令、つまりプログラミングのソースコードになります。

  • .dataディレクティブ

これ以下のテキストがデータになります。

  • .labelディレクティブ

データや命令にラベルを付けれます。アセンブリ言語はfor文がないので、goto文のように、ラベルにジャンプすることで制御します。ただしそのラベルが0x015Aのようにアドレスだと、ソースコードが読みづらいので、普通のアセンブリ言語にはラベル機能があります。

  • .numberディレクティブ

2バイト(16bit)の容量を確保し、その数値で初期化します。-32768..32767の10進数で16進数はではなりません。

  • #ディレクティブ

コメント

2.4データタイプ (Data Types)

アセンブリ言語には、明示的なデータ型はなく、データアクセス、ストアのルールがあるだけです。

  • このCPUのwordは16bits
  • メモリーロケーションは、16bit wide
    • アドレス0なら、bits 0…15
    • アドレス1なら、bits 16…31
  • 256メモリロケーション(addressable words)
    • テキストメモリー、データメモリー
    • 0-255まで
    • $pcは、テキストメモリーでのみ使われます。
  • 命令で、即値(Immediate value)とアドレスでは、8bitが使われます。
    • これがアドレスとして使われる場合は、unsingedで、0-255です。
    • addなど命令に使われる倍は、8-bit valueはデータセグメントのアドレスを表します。
    • beqz分岐命令の場合は、8-bit valueは、テキストセグメントを参照するのに使います。
    • addiなどの即値命令の場合は、-128…127の8-bit integer valueとして使います。

2.5 Designing an Assembly Language

アセンブリー言語をデザインする。

命令を3つの要点で分けて考えます。メモリー間のデータ転送命令、演算命令、プログラム制御命令を3つにわけて考えましょうという事です。

  1. メインメモリーのデータを、レジスター(≒オペランドスタック)に移動できる命令を用意
  2. ALUの演算命令を用意
  3. プログラム制御。普通はbranch演算で提供します。つまりJUMP命令。

2.5.1 Transferring data from main memory to internal CPU memory

メインメモリーからCPU内のメモリーへのデータ転送

今回実装する1アドレス命令方式はレジスターが1つです。アキュムレーター(=Accumulator=累積器)は、$acで示し、CPU内でプログラマーがいろいろ使える唯一のメモリーです。

CPUの処理の流れとしては以下になります。

  1. メインメモリーからレジスターにデータをロード
  2. 演算処理
  3. 処理結果をメインメモリーにストア

アキュムレーターは8bitの1個だけなので、命令とデータを保持するために、メインメモリーに頼らなければなりません。このコンピュータでは、データメモリからアキュムレーター間の転送には、add、sub、store命令を使います。

add命令、sub命令

オペランドには、ラベル、またはメモリーアドレスです。

このアセンブリ言語にload命令はありませんが、clacで$acを0にクリアして、add Aで、メモリーAから$acに値を加算しているので、以下のように$ac = 0 + labelAをやっているので結局はload命令があるのと同じことです。

STOR命令

オペランドには、ラベル、またはメモリーアドレスです。$acの値を、オペランドに保持します。

2.5.2 Set of valid ALU operations

次に考慮することは、ALUの命令セットです。このコンピュータは、加算と減算(add,sub)を用意します。

2.5.3 Program Control(Branching)

プログラム制御(分岐)

使いやすいプログラミングには、ifやloop構造があります。この1アドレス命令方式(one-address CPU)では、Branch-if-equal-zero(beqz)命令を用意します。

これはMIPSプロセッサーで使われる名称のようです。x86のアセンブリー言語の場合は、JE(Jump if equal)、JZ(Jump if zero)がよく使われます。

もし$acが0なら、EndLoopラベルに分岐します。

2.5.4 Assembler Instructions

 

  • add[label|address]
    • $ac += data memory address
  • addi immediate
    • $ac += immediate
  • beqz [label|address]
    • if ($ac == 0) $pc = address.
  • clac
    • $ac  = 0
  • sub [label|address]
    • $ac -= data memory address
  • subi immediate
    • $ac -= immediate
  • stor [label|address]
    • data memory = $ac
  • noop
    • $pc++

2.6 Assembler Programs

2.5まででやってきたことを踏まえたプログラミングサンプルです。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA