我正在为特定的指令集编写汇编程序。 我坚持的阶段是我正在使用开关案例将指令转换为各自的指令 十六进制代码因此,对于25条指令,我使用了25个案例,我的代码转换了指令。有没有更好的方法来转换这些指令,而不是使用这么多的开关案例。 ISA可以在这里找到:https://docs.google.com/file/d/1uIzgSaTD-onlr6f3ltmZkGRuYpAxIKqKSvOSAYsjREeBawYD7vRE4q42i9dM/edit?usp=sharing
答案 0 :(得分: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) {
// ...
}
}
答案 1 :(得分: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 :(得分:0)
您将获得在某些时候枚举所有指令的复杂性。但我很无聊,所以这里有一种方法可以将复杂性移开一点就是这样做,伪代码:
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);
}
}
虽然找到所有继承的函数等,但这种方法可能比开关慢,但这只是猜测。