如何編寫將彙編代碼翻譯成機器碼的程序?
我現在需要編寫一個將彙編代碼翻譯成機器碼的程序,請問該如何做?難度有多大?
還沒人提到Wilson,必須來抖個機靈。
Wilson是一個用Ruby寫的x86彙編器(庫)。它的實現全在一個文件里:https://github.com/seattlerb/wilson/blob/master/lib/wilson.rb
看到沒?直接把NASM的文檔放在文件末尾,在初始化這個庫的時候把文檔讀出來然後逐行parse出指令格式的定義然後通過Ruby的動態性添加相應的方法來對應指令。作者說了這個庫就是個抖機靈,但用還是能用…P.S. 這玩兒的作者可能不知道Ruby里__END__之後的內容可以直接用DATA.read讀出來?謝邀,你要做的是一個彙編器。這是一個蛋疼的活,關鍵是細緻,而不在於難度,你需要找到對應體系結構的指令對照表,如MOV命令在那張表對應的Machine Code是什麼,隨後讀取剩下的部分,當然在讀取地址的時候可能也會涉及到十六進位到二進位的一個轉換,因為一個好的彙編器允許程序員使用十六進位,最後你的彙編器應該完成類似下圖的工作:BTW,若你的體系結構不是特別小眾,為何不利用GCC呢?
不難,非常機械化,就是照著手冊抄。當然如果你能總結一下編碼的規律,也是能大大減少代碼量的。
以 x86-64 為例,編碼格式可以參照 X86-64 Instruction Encoding (頁面尾部有官方的手冊,不過那太長了..)。一些可以參考的,對編碼規律進行了歸納總結的,較為簡短精練並且可讀性高的實現有:
- asmjit (asmjit/x86assembler.h at 515d854d10e656fe410663d77400bf6ab5627541 · kobalicek/asmjit · GitHub)- PyPy (pypy / pypy/ source / rpython / jit / backend / x86 / rx86.py)- Dart (bleeding_edge/assembler_x64.cc at e9bcfb8d1ff00a6c6b872c3a6fb186a509de5bdf · dart-lang/bleeding_edge · GitHub)
以前也折騰過,回答的內容希望對題主有幫助。
實現彙編器真的是體力活,如果實現x86彙編器,光這本開發人員手冊《Intel速 64 and IA-32 Architectures Software Developer Manuals》夠慢慢啃的。不過,通過手冊搞清楚指令格式後,可以使用這個geek32 edition速查彙編指令對應的機器碼。還有這個也推薦題主看看: Real x86 Instructions。
在彙編器可以將彙編指令轉為機器碼,生成二進位文件後,要生成OS下的可執行程序或庫文件,就得開始讀OS下的可執行程序格式說明文檔(如:WINDOWS的PE/COFF文件格式說明,LINUX的ELF文件格式說明等),按OS的ABI規範生成程序文件。
如果真要自己寫一個,可以試著讀讀 NASM(http://www.nasm.us/)的代碼,參考參考。
參考文檔:1、PE/COFF :http://download.microsoft.com/download/e/b/a/eba1050f-a31d-436b-9281-92cdfeae4b45/pecoff.doc
2、ELF : http://www.skyfree.org/linux/references/ELF_Format.pdf3、System V ABI : http://refspecs.linuxbase.org/elf/gabi41.pdf有本書叫《PDP-11機器語言與彙編語言程序設計》。上世紀八十年代的貨,講的是機器語言,還有彙編以及彙編原理,你可以看看。順帶說一句,我們學校教授編譯原理,可從來沒聽過有學校教彙編原理,畢竟現在除了學底層的,已經很少有人學彙編了,即使學彙編也只是淺嘗輒止講講8086。。而直接寫彙編器的我想沒幾個。
除了機械翻譯指令外,還要計算相對地址,還要符合目標文件的格式(Elf COFF等) , 系統的ABI (什麼樣的重定位項等)
掃描兩遍,第一遍把助記符,操作數生成機器碼,不知道內容的,比如標號,留佔位符代替,並且生成每條指令的地址和標號地址。第二遍把所有已標號為操作數的預留空間給填上。 兩遍掃描也不是必須的。
可以參考這本書:Assemblers and Loaders (Ellis Horwood Series in Computers and Their Applications): David Salomon: 9780130525642: Amazon.com: Books真 。 體力活.
寫過一個x86反彙編引擎(機器碼到彙編代碼),超級蛋疼的工作,愣是寫了一個多月。沒啥技術含量,但絕對鍛煉你的耐心。查手冊,寫個大switch。
找對應指令集的對照表。以前我做過把有個單片機的機器碼翻譯成彙編。就是很繁瑣。
彙編編譯器不難的╮(╯▽╰)╭
推薦閱讀:
※clang編譯CUDA程序,為何會生成多個LLVM bitcode文件?
※為什麼有了 遞歸, select-case, 約定數據結構(數組) 就可以證明圖靈完備?
另為什麼遞歸如此重要?
※C語言或C++語言如何實現尾調用消除?
※如何理解ByteCode、IL、彙編等底層語言與上層語言的對應關係?
※如何學寫一個編譯器後端?