特定の命令セット用のアセンブラを書いています。私が立ち往生している段階は、スイッチケースを使用して命令をそれぞれの16進コードに変換していることです。したがって、25 の命令に対して、コードが命令を変換する 25 のケースを使用しています。非常に多くのスイッチケースを使用するのではなく、これらの命令を変換するより良い方法はありますか? ISA は次の場所にあります。
1324 次
3 に答える
4
アセンブラをコーディングしたとき、各命令のエンコーディングとそれを実行するために呼び出すコールバックを格納する辞書がいくつかありました (それは C# です。気にしませんか? ;) ):
class Processor {
static Dictionary<string, int> _encodings = new Dictionary<string, int>() {
{ "mov", 0x00000032 },
{ "add", 0x00000051 }
// etc.
};
static Dictionary<string, Action<object, object>> _callbacks =
new Dictionary<string, Action<object, object>>() {
{ "mov", executeMov },
{ "add", executeAdd }
// ect
};
void executeMov(object o1, object o2) {
// ...
}
void executeAdd(objecy o1, object o2) {
// ...
}
}
于 2013-03-03T09:19:54.163 に答える
2
各命令を記述する構造体の配列を作成します。構造には次のものが含まれます。
- 命令ニーモニック (例
"AND"
) - 命令オペコード (例
0
) - 命令オペランドの種類 (例:
no operand
、register operand
、memory operand
、immediate operand
、2 register operands
、register operand + memory operand
、register operand + immediate operand
などmemory operand + immediate operand
)
次に、ニーモニックで配列を検索し、この命令が受け入れるオペランドを確認し、それを入力アセンブリのオペランドと一致させることができます。一致しない場合は、同じ命令と同じニーモニックの別のバージョンがあるかどうかを確認しますが、オペランドが異なり、一致を繰り返します ( AND
2 つのフレーバーがあるように見えます)。配列全体に一致するものがない場合、エラーで失敗します。
シンプル、汎用、拡張可能。そして、パフォーマンス要件がない限り、これを速度のために最適化することは気にしません。
于 2013-03-03T11:06:07.433 に答える
0
ある時点で、すべての命令を列挙するという複雑さが生じます。しかし、私は退屈なので、複雑さを少し取り除く1つの方法は、次のような擬似コードを行うことです:
abstract class InstructionWriter
void writeInstruction(file, data)
...lots of different instruction writers...
void setupWriters() {
writers = Container<InstructionWriter>(NUM_OP_CODES);
writers[OPCODE1] = writerForOpCode1();
writers[OPCODE2] = writerForOpCode2();
...
}
次に、実際の書き込みは次のように書き換えることができます
void writeInstructions(program) {
file = open(binaryfile)
for(opcode o in program) {
writers[o.opcode].write(file, o.data);
}
}
このアプローチは、継承されたすべての関数を見つけるなど、おそらくスイッチよりも遅くなりますが、それは単なる推測です。
于 2013-03-03T09:20:13.280 に答える