포럼: 開発者 (Thread #21088)

メモリ管理クラスの詳細と例外と書き方について (2008-12-26 22:12 by nnctj05 #40833)

依田です。作成お疲れ様。
メモリ管理クラスのメンバ関数と、考えられる例外を以下にリストします。
・ユーザが指定する printMemory の i_address_start, i_address_size は入力クラスで例外処理するのでここでは判定しない
・flagtype はプログラマが渡すものなので例外処理はしない
・プログラマが指定する i_address, i_value は下位16ビットをマスクするのでどんな値を渡しても例外は発生しない
とします。

で聞きたいのですが
・i_gr_num はどこでエラー処理を行うか
 たとえばPCのメモリから読み出した命令が 「1290 FFFF」 だった場合、LEA GR9,65535 となります。
  ->実行クラス(デコード時?)で例外を投げるかメモリ管理クラスで例外を投げるか。

・エラーとして投げるクラス名はコーディングする人が決めて良いのか?(catchしたときの動作は任せるとして。)
またその命名規則をどうするか。

ある書籍では以下のように例外を書いてました(参考までに)。
namespace Error {
struct Zero_divide { };

struct Syntax_error {
const char* p;
Syntax_error(const char* q) { p = q; }
};
}

そして例外の箇所で[throw Error::Syntax_error("bad token");]


・構文の書き方、括弧の付け方をどうするか?たとえば以下の場合、空白の場所も決めるかどうか(それともそこまで決めないか)、中括弧の改行の有無など。
 for(int i; i<10; i++){
 }
コーディングする人に任せるなら自分流になってしまいます。

でクラスが完成したら、もちろんリリースのところに上げておきます。
よろしく。


#define MM_DEFAULT_PRINTMEMORYSIZE 5 //デフォルトで5番地分メモリ表示(暫定)

enum flagtype{
FLAG_PLUS, FLAG_ZERO, FLAG_MINUS
};

class MemoryManagement
{
public: //公開メンバ

//コンストラクタ・デストラクタ
MemoryManagement(char *pc_filename_input);
~MemoryManagement();
  //err--読み込みファイルが存在しない
  //err--ファイルのフォーマットエラー


//表示関数
void printAllRegister(void);
void printMemory(int i_address_start, int i_address_size = MM_DEFAULT_PRINTMEMORYSIZE);
void printMemory(char *pc_filename_output, int i_address_start, int i_address_size = MM_DEFAULT_PRINTMEMORYSIZE);
void printBreakPoint(void);
  //err--出力ファイルが開けない(書き込み禁止、使用できない記号を含んだファイル名など)

//ブレークポイント
void setBreakPoint(int i_address);
void removeBreakPoint(int i_address);
bool checkBreakPoint(int i_address); //false:BPがセットされていない

//プログラムカウンタ
void setProgramCounter(int i_address);
int getProgramCounter(void);
void addProgramCounter(int i_value = 1);

//汎用レジスタ
void setGeneralRegister(int i_gr_num, int i_value);
int getGeneralRegister(int i_gr_num);
void addGeneralRegister(int i_gr_num, int i_value);

//フラグレジスタ
void setFlagRegister(flagtype ft_flag_sign);
flagtype getFlagRegister(void);

//汎用メモリ
void setMemory(int i_address, int i_value);
int getMemory(int i_address);

}

RE: メモリ管理クラスの詳細と例外と書き方について (2009-01-01 09:40 by fujiken17 #40890)

tanakaです。


> ・i_gr_num はどこでエラー処理を行うか
>  たとえばPCのメモリから読み出した命令が 「1290 FFFF」 だった場合、LEA GR9,65535 となります。
>   ->実行クラス(デコード時?)で例外を投げるかメモリ管理クラスで例外を投げるか。


回答.gr9の例のように、grのOutOfRangeは、実行クラスの実行状態に依らず必ず例外ですので、メモリ管理クラスの管轄とします。

アドレスのように、オペコードによっては例外になったり、ならなかったり、といったものは実行クラスの管轄です。
例えば、#FFFFがシステム領域(つまりユーザが一意にアクセスできない)である場合、LEA gr0,#FFFFはOKですが、LD gr0,#FFFFはエラーです。

> ・エラーとして投げるクラス名はコーディングする人が決めて良いのか?(catchしたときの動作は任せるとして。)
> またその命名規則をどうするか。
>
> ある書籍では以下のように例外を書いてました(参考までに)。
> namespace Error {
> struct Zero_divide { };
>
> struct Syntax_error {
> const char* p;
> Syntax_error(const char* q) { p = q; }
> };
> }

回答.エラーのクラス名はクラス命名規則に従います。
また、エラー名は関数命名規則に従います。
すべてのエラー系クラスはGeneralErrorを継承してください。
GeneralErrorクラスは、画面への出力処理の呼び出し、コマンド入力への復帰処理などをオーバーロードしています。


> ・構文の書き方、括弧の付け方をどうするか?たとえば以下の場合、空白の場所も決めるかどうか(それともそこまで決めないか)、中括弧の改行の有無など。
>  for(int i; i<10; i++){
>  }
> コーディングする人に任せるなら自分流になってしまいます。

回答.構文の書き方などは自己流でかまいませんが、必ず一つのファイル内では統一してください。統一されていないソースコードは読みにくいことこの上ありません。これだけは絶対守ってください。お願いします。


> でクラスが完成したら、もちろんリリースのところに上げておきます。
> よろしく。
>
>
> #define MM_DEFAULT_PRINTMEMORYSIZE 5 //デフォルトで5番地分メモリ表示(暫定)
>
> enum flagtype{
> FLAG_PLUS, FLAG_ZERO, FLAG_MINUS
> };
>
> class MemoryManagement
> {
> public: //公開メンバ
>
> //コンストラクタ・デストラクタ
> MemoryManagement(char *pc_filename_input);
> ~MemoryManagement();
>   //err--読み込みファイルが存在しない
>   //err--ファイルのフォーマットエラー
>
>
> //表示関数
> void printAllRegister(void);
> void printMemory(int i_address_start, int i_address_size = MM_DEFAULT_PRINTMEMORYSIZE);
> void printMemory(char *pc_filename_output, int i_address_start, int i_address_size = MM_DEFAULT_PRINTMEMORYSIZE);
> void printBreakPoint(void);
>   //err--出力ファイルが開けない(書き込み禁止、使用できない記号を含んだファイル名など)
>
> //ブレークポイント
> void setBreakPoint(int i_address);
> void removeBreakPoint(int i_address);
> bool checkBreakPoint(int i_address); //false:BPがセットされていない
>
> //プログラムカウンタ
> void setProgramCounter(int i_address);
> int getProgramCounter(void);
> void addProgramCounter(int i_value = 1);
>
> //汎用レジスタ
> void setGeneralRegister(int i_gr_num, int i_value);
> int getGeneralRegister(int i_gr_num);
> void addGeneralRegister(int i_gr_num, int i_value);
>
> //フラグレジスタ
> void setFlagRegister(flagtype ft_flag_sign);
> flagtype getFlagRegister(void);
>
> //汎用メモリ
> void setMemory(int i_address, int i_value);
> int getMemory(int i_address);
>
> }
>
Reply to #40833