非専門的シンギュラリティー研究所

無限に動き続けるシステムを表す方法を AI なども使って考えていきます。

アセンブラ(7)

executeInstruction 関数の処理

Visual Studio で補完されたプログラムと ChatGPT で作ってもらったプログラムを元に改造しました。まだ動くようにはなっていません。

executeInstruction 関数の move 系命令の処理は以下のようになります。『X68000ベスト・プログラミング入門』に 68000 の命令セットが載っているのでこれを参考にしています。

move, movea, moveq

「move src, dst」は src の値を取得して dst に設定します。moveq も同様です。movea は動作が異なるようですが、説明がよくわからないので今のところ同じ動作になっています。

フラグは N と Z は値によって変化し、V と C は 0、X は不明です。

    if (instruction.is_move_instruction()) {
        // MOVE命令の処理
        if (operands.size() != 2) {
            cerr << "Invalid MOVE instruction: " << line << endl;
            return;
        }
        int32_t value = operands[0].get_value(instruction.data_size());
        operands[1].set_value(value, instruction.data_size());
        if (instruction.modifies_flags()) {
            cpu.set_value_status(value, instruction.data_size());
        }
    }
movem

「move src, dst」は

それ以外の場合もあるようですが詳細は不明です(対応していません)。

フラグは変化しません。

レジスタリストの指定は

  • 「%dk-%dl/%am-%an」のようなパターンか、
  • 「#数値」(即値)で表されるビットマスク

となります。詳細は不明です。ここでは

  • プッシュのときは a7, ... , a0, d7, ... , d0 の順
  • ポップのときは d0, ... , d7, a0, ... , a7 の順

とします。ビットマスクは

  • プッシュのときは上位から a7, ... , a0, d7, ... , d0 の順
  • ポップのときは上位から d0, ... , d7, a0, ... , a7 の順

とします。

    else if (instruction.is_movem_instruction()) {
        // MOVEM命令の処理
        if (operands.size() != 2) {
            cerr << "Invalid MOVEM instruction: " << line << endl;
            return;
        }
        Operand& src = operands[0];
        Operand& dst = operands[1];
        vector<string> regs = src.get_src_reglist();
        if(regs.size() >= 2) {
            // src がレジスタリストの場合
            for (auto it = regs.rbegin(); it != regs.rend(); ++it) {
                dst.set_value(cpu.getRegisterValue(*it), instruction.data_size());
            }
        }
        else {
            // dst がレジスタリストの場合
            vector<string> regs = dst.get_dst_reglist();
            for (const string& reg : regs) {
                int32_t value = src.get_value(instruction.data_size());
                cpu.setRegisterValue(reg, value);
            }
        }
    }