簡體   English   中英

制作匯編程序的設計模式

[英]Design Pattern For Making An Assembler

我正在制作8051匯編程序。

在所有東西都是一個讀取下一個令牌的標記器之前,設置錯誤標志,識別EOF等。
然后是編譯器的主循環,它讀取下一個標記並檢查有效的助記符:

mnemonic= NextToken();
if (mnemonic.Error)
{
    //throw some error
}
else if (mnemonic.Text == "ADD")
{
    ...
}
else if (mnemonic.Text == "ADDC")
{
    ...
}

它繼續有幾個案例。 更糟糕的是每個案例中的代碼,它檢查有效參數然后將其轉換為編譯代碼。 現在它看起來像這樣:

if (mnemonic.Text == "MOV")
{
    arg1 = NextToken();
    if (arg1.Error) { /* throw error */ break; }
    arg2 = NextToken();
    if (arg2.Error) { /* throw error */ break; }

    if (arg1.Text == "A")
    {
        if (arg2.Text == "B")
            output << 0x1234; //Example compiled code
        else if (arg2.Text == "@B")
            output << 0x5678; //Example compiled code
        else
            /* throw "Invalid parameters" */
    }
    else if (arg1.Text == "B")
    {
        if (arg2.Text == "A")
            output << 0x9ABC; //Example compiled code
        else if (arg2.Text == "@A")
            output << 0x0DEF; //Example compiled code
        else
            /* throw "Invalid parameters" */
    }
}

對於每個助記符,我必須檢查有效參數,然后創建正確的編譯代碼。 用於檢查每種情況下每個助記符重復的有效參數的非常相似的代碼。

那么是否有改進此代碼的設計模式?
或者只是一種更簡單的方法來實現它?

編輯:我接受了基座的回答,多虧了他。 如果你有這方面的想法,我將很樂意學習它們。 謝謝大家。

多年來我編寫了許多匯編程序來進行手工解析,坦率地說,使用語法語言和解析器生成器可能會更好。

這就是原因 - 典型的裝配線可能看起來像這樣:

[label:] [instruction|directive][newline]

並且指令將是:

plain-mnemonic|mnemonic-withargs

並且指令將是:

plain-directive|directive-withargs

等等

有了像Gold這樣的解析器生成器,你應該可以在幾個小時內刪除8051的語法。 這種過度解析的優點是,您可以在匯編代碼中使用足夠復雜的表達式,如:

.define kMagicNumber 0xdeadbeef
CMPA #(2 * kMagicNumber + 1)

這可能是一個真正的熊手工做。

如果您想手動完成,請列出所有助記符,其中還包括它們支持的各種允許尋址模式以及每種尋址模式,每個變量將采用的字節數以及它​​的操作碼。 像這樣的東西:

enum {
    Implied = 1, Direct = 2, Extended = 4, Indexed = 8 // etc
} AddressingMode; 

/* for a 4 char mnemonic, this struct will be 5 bytes.  A typical small processor
 * has on the order of 100 instructions, making this table come in at ~500 bytes when all
 * is said and done.
 * The time to binary search that will be, worst case 8 compares on the mnemonic.
 * I claim that I/O will take way more time than look up.
 * You will also need a table and/or a routine that given a mnemonic and addressing mode
 * will give you the actual opcode.
 */

struct InstructionInfo {
    char Mnemonic[4];
    char AddessingMode;
}

/* order them by mnemonic */
static InstructionInfo instrs[] = {
    { {'A', 'D', 'D', '\0'}, Direct|Extended|Indexed },
    { {'A', 'D', 'D', 'A'}, Direct|Extended|Indexed },
    { {'S', 'U', 'B', '\0'}, Direct|Extended|Indexed },
    { {'S', 'U', 'B', 'A'}, Direct|Extended|Indexed }
}; /* etc */

static int nInstrs = sizeof(instrs)/sizeof(InstrcutionInfo);

InstructionInfo *GetInstruction(char *mnemonic) {
   /* binary search for mnemonic */
}

int InstructionSize(AddressingMode mode)
{
    switch (mode) {
    case Inplied: return 1;
    / * etc */
    }
 }

然后,您將獲得每個指令的列表,而這些指令又包含所有尋址模式的列表。

所以你的解析器變成這樣:

char *line = ReadLine();
int nextStart = 0;
int labelLen;
char *label = GetLabel(line, &labelLen, nextStart, &nextStart); // may be empty
int mnemonicLen;
char *mnemonic = GetMnemonic(line, &mnemonicLen, nextStart, &nextStart); // may be empty
if (IsOpcode(mnemonic, mnemonicLen)) {
    AddressingModeInfo info = GetAddressingModeInfo(line, nextStart, &nextStart);
    if (IsValidInstruction(mnemonic, info)) {
        GenerateCode(mnemonic, info);
    }
    else throw new BadInstructionException(mnemonic, info);
}
else if (IsDirective()) { /* etc. */ }

是。 大多數匯編程序使用描述指令的數據表:助記符,操作碼,操作數表等。

我建議查看as的源代碼。 我找到它時遇到了一些麻煩。 這里 (感謝Hossein。)

我認為你應該研究訪客模式。 它可能不會使您的代碼更簡單,但會減少耦合並提高可重用性。 SableCC是一個用於構建廣泛使用它的編譯器的Java框架。

你看過“Command Dispatcher”模式嗎?

http://en.wikipedia.org/wiki/Command_pattern

一般的想法是創建一個處理每個指令(命令)的對象,並創建一個將每個指令映射到處理程序類的查找表。 每個命令類都有一個公共接口(例如Command.Execute(* args)),這肯定會給你一個比你當前巨大的switch語句更清晰/更靈活的設計。

當我使用Microcode模擬器工具時,我將所有內容都轉換為Instruction類的后代。 From Instruction是類別類,例如Arithmetic_InstructionBranch_Instruction 我使用工廠模式來創建實例。

您最好的選擇可能是獲得匯編語言語法規范。 寫一個詞法分析器轉換為代幣(**請不要使用if-elseif-else梯子)。 然后基於語義,發出代碼。

很久以前,匯編程序至少有兩次傳遞:第一次解析常量並形成骨架代碼(包括符號表)。 第二步是產生更具體或絕對的價值。

你最近讀過龍書嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM