3

私はアセンブラー設計分野の初心者です。私は機械用に独自のアセンブラを設計しています。現在、私のアセンブラは最初のトークンを取得し(それが命令であると想定しています)、次に対応するオブジェクトコードを生成しようとします。次に、トークンをニーモニックのプールと照合してから、対応するobjコードを生成する必要があります。問題は、私が現在if-else構文を使用していることです。

if(strcmp(mnemonic_read, "mov")==0)
// generate code for mov instr
else if(strcmp(mnemonic_read,"cmp")==0)
// generate code for cmp

多くのif-elseステートメントを使用せずにこれらすべてを実行できますか?mnemonic_read文字列変数を介して関数を呼び出すことはできますか?

4

3 に答える 3

2

これは一般的な問題であり、一般的な解決策があります(haroldが提案しています)。

*nix環境でうまく機能するlex/yaccまたはflex/bisonを調べることをお勧めします。Antlrも同様のことをしますが、Javaを使用します。

たとえば、lexを使用できます(http://dinosaur.compilertools.net/から):

Lex sourceは、正規表現と対応するプログラムフラグメントのテーブルです。テーブルは、入力ストリームを読み取り、それを出力ストリームにコピーし、指定された式に一致する文字列に入力を分割するプログラムに変換されます。このような各文字列が認識されると、対応するプログラムフラグメントが実行されます。

したがって、lexでは、トークン(正規表現と一致する)と、生成される対応するコードを指定できます。トークンをyacc(さらに別のコンパイラコンパイラ)にフィードして、新しい言語のコンパイラを生成することもできます。

例を含む便利なガイドは次のとおりです。http://ds9a.nl/lex-yacc/cvs/lex-yacc-howto.html

于 2012-09-07T14:58:42.213 に答える
2

数十から数十のif-elseステートメントやswitch-constructの代わりに、一種のハッシュテーブルを使用する必要があります。

また、「アセンブラロジック」を単純なパーサーロジックから分離してください。

于 2012-09-07T13:13:59.683 に答える
1

キーワードを格納するために、ハッシュマップのある種の連想配列が必要になる可能性があります。これは基本的に任意の型でインデックス付けされた配列であり(問題に役立つのは文字列です)、そこに含まれる値は関数ポインターである可能性があります。次に、解析されたコマンドごとに異なる関数を呼び出します。

コードスニペットからC++を使用していると仮定すると、次のように記述できます。

// map strings to function pointers 
// which take a string (maybe the operands) as parameter
map<string, void (*)(string)> commands;

コンストラクターまたは同様の初期化ルーチンで、ハッシュマップ(基本的にジャンプテーブルとして機能します)を設定する必要があります。

init() {        
    commands["mov"] = cmd_mov;  
    commands["cmp"] = cmd_cmp;
    ...  
}

void cmd_mov(string operands) {
    // generate move instruction
}
void cmd_cmp(string operands) {
    // generate cmp instruction
}

関数を呼び出すのは簡単です

string mnemonic = mnemonic_read_cmd();
string operands = mnemonic_read_op();
*(commands[mnemonic])(operands);

関数ごとに異なる数のパラメーターが必要な場合は、単純な関数ポインターの代わりに、functionoidまたはが正しい選択である可能性があります。boost::function

于 2012-10-05T11:49:35.210 に答える