2013-03-03 32 views
1

我正在爲特定指令集編寫彙編程序。 我堅持的階段是我使用開關盒將指令轉換爲它們各自的 十六進制代碼。因此,對於25條指令,我使用了25個代碼來轉換指令。有沒有更好的方法來轉換這些指令,而不是使用這麼多的開關情況。 ISA可以在這裏找到:https://docs.google.com/file/d/1uIzgSaTD-onlr6f3ltmZkGRuYpAxIKqKSvOSAYsjREeBawYD7vRE4q42i9dM/edit?usp=sharing編寫彙編程序的替代技術

+0

更好? (爲什麼你不喜歡switch/case聲明?) – thebjorn 2013-03-03 09:17:35

+0

這不是我不喜歡的東西,只是好奇如果有更好的方法來做這件事。 – anichhangani 2013-03-03 09:20:58

+0

考慮表驅動設計。 – 2013-03-03 09:57:09

回答

3

當我編寫我的彙編程序時,我有幾個字典存儲每個指令的編碼和回調來調用執行它(這是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) { 
     // ... 
    } 
} 
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); 
    } 
} 

這種做法可能會盡管找到所有繼承的函數等,但比開關慢,但這只是一個猜測。

1

我會創建一個描述每條指令的結構數組。該結構將包含:

  • 指令助記符(例如"AND"
  • 指令操作碼(例如0
  • 指令的操作數類型(例如no operandregister operandmemory operandimmediate operand2 register operandsregister operand + memory operandregister operand + immediate operandmemory operand + immediate operand,等等)

然後,你可以只是由數據庫搜索數組並查看該指令接受哪些操作數,並與輸入程序集的操作數匹配。如果沒有匹配,則檢查是否有另一個版本的相同指令和相同的助記符,但具有不同的操作數並重復匹配(看起來像AND有兩種風格)。如果整個陣列中沒有匹配,則會失敗並顯示錯誤。

簡單,通用,可擴展。除非性能要求,否則我不打算優化速度。