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

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

アセンブラ(12)

executeInstruction 関数の処理(6) 乗除算命令

乗除算命令には以下のようなものがあります。

mulu, muls

「mulu src, dst」は dst と src の符号なしの積を dst に設定します。「muls src, dst」は dst と src の符号ありの積を dst に設定します。

フラグは N と Z は値によって変化し、V はオーバーフロー発生の時 1、そうでないとき 0 です。C は 0、X は変化しません。

    else if (instruction.is_mul_instruction()) {
        // MUL命令の処理
        if (operands.size() != 2) {
            cerr << "Invalid MUL instruction: " << line << endl;
            return;
        }
        Operand& src = operands[0];
        Operand& dst = operands[1];
        int32_t src_value = src.get_value(instruction.data_size());
        int32_t dst_value = dst.get_value(instruction.data_size());
        if(instruction.is_unsigned_operation()) {
            // 符号なし乗算
            uint32_t u_src_value = static_cast<uint32_t>(src_value);
            uint32_t u_dst_value = static_cast<uint32_t>(dst_value);
            uint32_t value = u_dst_value * u_src_value;
            dst.set_value(value, instruction.data_size());
            if (instruction.modifies_flags()) {
                cpu.set_value_status(value, instruction.data_size());
            }
        }
        else {
            // 符号あり乗算
            int32_t value = dst_value * src_value;
            dst.set_value(value, instruction.data_size());
            if (instruction.modifies_flags()) {
                cpu.set_value_status(value, instruction.data_size());
            }
        }
    }
divu, divs

「divu src, dst」は dst を src で割った符号なしの商を dst に設定します。「divs src, dst」は dst と src で割った符号ありの商を dst に設定します。

フラグは N と Z は値によって変化し、V はオーバーフロー発生の時 1、そうでないとき 0 です。C は 0、X は変化しません。

    else if (instruction.is_div_instruction()) {
        // DIV命令の処理
        if (operands.size() != 2) {
            cerr << "Invalid DIV instruction: " << line << endl;
            return;
        }
        Operand& src = operands[0];
        Operand& dst = operands[1];
        int32_t src_value = src.get_value(instruction.data_size());
        int32_t dst_value = dst.get_value(instruction.data_size());
        if (instruction.is_unsigned_operation()) {
            // 符号なし除算
            uint32_t u_src_value = static_cast<uint32_t>(src_value);
            uint32_t u_dst_value = static_cast<uint32_t>(dst_value);
            uint32_t value = u_dst_value / u_src_value;
            dst.set_value(value, instruction.data_size());
            if (instruction.modifies_flags()) {
                cpu.set_value_status(value, instruction.data_size());
            }
        }
        else {
            // 符号あり除算
            int32_t value = dst_value / src_value;
            dst.set_value(value, instruction.data_size());
            if (instruction.modifies_flags()) {
                cpu.set_value_status(value, instruction.data_size());
            }
        }
    }