[英]How to write a X86_64 _assembler_?
目標:我想編寫一個X86_64匯編程序。 注意:標記為社區維基
背景:我熟悉C.我以前寫過MIPS匯編。 我寫了一些x86程序集。 但是,我想編寫一個x86_64匯編程序 - 它應該輸出我可以跳轉到並開始執行的機器代碼(就像在JIT中一樣)。
問題是:解決這個問題的最佳方法是什么? 我意識到這個問題看起來有點大。 我想從一個基本的最小集開始:
只是一個基本的設置,使圖靈完成。 有人做過嗎? 建議/資源?
像任何其他“編譯器”一樣,匯編程序最好寫成一個詞法分析器,輸入語言語法處理器。
匯編語言通常比常規編譯語言更容易,因為您不需要擔心跨越行邊界的構造,並且格式通常是固定的。
兩年前我為一個(虛構的)CPU編寫了一個匯編程序用於教育目的,它基本上將每一行視為:
:loop
)。 mov
)。 ax,$1
)。 最簡單的方法是確保令牌易於區分。
這就是為什么我制定了標簽必須開始的規則:
- 它使得對線的分析變得更加容易。 處理生產線的過程是:
;
在字符串外面到行尾)。 您可以輕松地堅持不同的操作數也有特殊的標記,讓您的生活更輕松。 所有這一切都假設您可以控制輸入格式。 如果您需要使用英特爾或AT&T格式,那就更難了。
我接近它的方式是有一個簡單的每個操作函數被調用(例如, doJmp
, doCall
, doRet
),並且該函數決定了操作數中允許的內容。
例如, doCall
只允許數字或標簽, doRet
不允許任何內容。
例如,這是來自encInstr
函數的代碼段:
private static MultiRet encInstr(
boolean ignoreVars,
String opcode,
String operands)
{
if (opcode.length() == 0) return hlprNone(ignoreVars);
if (opcode.equals("defb")) return hlprByte(ignoreVars,operands);
if (opcode.equals("defbr")) return hlprByteR(ignoreVars,operands);
if (opcode.equals("defs")) return hlprString(ignoreVars,operands);
if (opcode.equals("defw")) return hlprWord(ignoreVars,operands);
if (opcode.equals("defwr")) return hlprWordR(ignoreVars,operands);
if (opcode.equals("equ")) return hlprNone(ignoreVars);
if (opcode.equals("org")) return hlprNone(ignoreVars);
if (opcode.equals("adc")) return hlprTwoReg(ignoreVars,0x0a,operands);
if (opcode.equals("add")) return hlprTwoReg(ignoreVars,0x09,operands);
if (opcode.equals("and")) return hlprTwoReg(ignoreVars,0x0d,operands);
hlpr...
函數只是獲取操作數並返回包含指令的字節數組。 當許多操作具有類似的操作數要求時,它們很有用,例如adc ,
add and
`在上述情況下都需要兩個寄存器操作數(第二個參數控制了為指令返回的操作碼)。
通過使操作數的類型易於區分,您可以檢查提供的操作數,它們是否合法以及要生成哪些字節序列。 將操作分離為它們自己的函數提供了一個很好的邏輯結構。
此外,大多數CPU遵循從操作碼到操作的合理邏輯轉換(以使芯片設計者更容易生活),因此在所有允許例如索引尋址的操作碼上將進行非常類似的計算。
為了在允許可變長度指令的CPU中正確創建代碼,您最好在兩次通過中執行此操作。
在第一遍中,不生成代碼,只生成指令長度。 這允許您在遇到所有標簽時為其分配值。 第二遍將生成代碼,並且可以填充對這些標簽的引用,因為它們的值已知。 上面代碼段中的ignoreVars
用於此目的(返回代碼的字節序列,因此我們可以知道長度,但是對剛剛使用的符號的任何引用都是0)。
不要勸阻你,但已經有很多裝配工具有各種各樣的花里胡哨。 請考慮為像elftoolchain這樣的現有開源項目做出貢獻。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.