標籤:

如何使自己寫的編譯器生成可在 Windows 或 Linux 下直接運行的可執行文件?

一直想寫一個 C 語言的編譯器,但是只能讓編譯出來的代碼運行在自己寫的模仿 8086 彙編的「虛擬機」上。如果想讓編譯器生成可執行文件,需要學習什麼內容,用什麼開發工具?


vs的話可以把生成目標改成masm,這樣可以直接用vs編寫和調試彙編代碼,配合AsmDude - Visual Studio Marketplace插件簡直爽歪歪

具體操作步驟:

新建一個空的C++工程,然後

右鍵項目選擇此選項

選中masm

添加asm文件並開始編寫和調試吧!

註:如果報告類似

的錯誤的話,需要手動指定子系統

在此指定即可


都是什麼鬼答案,Win 看 PE,類 Unix 看 ELF 啊。


本回答通過Google 搜索

windows

手把手教你如何編寫、編譯彙編程序 - CSDN博客?

blog.csdn.net

linux

不是油條:彙編語言入門一:環境準備?

zhuanlan.zhihu.com圖標彙編入門?

zhuanlan.zhihu.com圖標

附上鏈接內容:

Windows@孫琨

1.背景

明天可能有第一節計算機操作系統上機課,所以今晚把學校發的操作系統實驗指導書預習了一下,發現指導書上的第一頁,用彙編語言寫,自己就一丁點看不懂。問題有2。問題1:用什麼工具寫彙編。問題2:如何編譯運行。既然預習了,自己覺得至少應該能用彙編,編寫個hello world出來吧。好吧,那麼下面,就詳細說一下,自己如何用彙編語言編寫出hello world。

2.具體學習過程

  (1)masm32開發包的下載

  要用彙編語言編程,首先得有個開發工具,彙編語言開發工具有多種,自己百度了一下,發現最多被談論的是masm,因此自己下了masm,並百度了有關內容介紹。本文僅介紹masm,介紹如何編寫符合masm語法規範的源代碼程序以及如何將源代碼程序進行編譯和鏈接,生成可執行的應用程序文件。

  masm開發包包括彙編器、連接器等工具,版本有多種,本文選擇使用masm32,其下載地址如下:http://www.masm32au.com/ ,然後再點第一項download

(2)masm32開發包的安裝指南

  masm32.zip文件下載以後,使用解縮工具將文件解壓,釋放出裡面的唯一文件install.exe。通過Windows資源管理器或控制台窗口執行install.exe以後,既可安裝開發包。install.exe執行後,中間會停下來問你是否重新配置開發包的安裝目錄。開發包安裝的默認目錄是c:masm32,你可以重新配置安裝目錄,比如重新配置安裝目錄是d:masm32 (以後我們就假定安裝目錄就是它)。安裝目錄配置好後按確認按鈕,安裝程序執行安裝。以後安裝過程只需要時間,其他沒有對話。

(3)masm32包中有關常用文件簡介

  masm32包即可以支持開發在DOS操作系統下運行的16位應用程序,也可以開發在Windows操作系統下運行的32位應用程序。在d:masm32目錄下有bin、include等多個子目錄,裡面存放著開發不同程序所用的工具文件和公用庫文件。由於本文是介紹DOS操作系統下16位彙編語言程序設計,所以一開始我們只介紹與此相關的幾個最常用的工具文件給您。

  將當前目錄切換到d:masm32in,我們會看到該目錄下有下面幾個文件:

  ml.exe——彙編器。我們編寫的源代碼文件就是通過它來彙編生成中間代碼文件,即通常擴展名為.obj的文件。

  link16.exe——連接器。由ml.exe彙編生成的.obj文件還不能直接上機運行,必須通過連接器link16.exe將其連接製作成擴展名為.exe(或者.com)的可執行文件才能上機。

(4)配置環境變數

  首先說說為什麼要配置環境變數。不嚴格地說,環境變數是操作系統幹活時用來參考的資源。還是結合我們剛剛安裝的開發包來說吧。請打開控制台窗口(可通過Windows附件里的「命令提示符」那個菜單打開),並輸入下面的指令:

  d:回車 (註:將當前盤切換到d:盤。回車是要求你按回車鍵執行指令,下同)

  cd masm32in 回車 (註:將當前目錄切換到d:masm32in)

  ml 回車 (註:執行ml.exe程序) // 注意是ml都是英文字母,不是m和數字1,自己在今晚嘗試過程中就犯過錯

  此時你會看到ml執行後在控制台窗口回顯的提示信息。這說明操作系統找到了 ml.exe並執行。那操作系統是怎麼尋找ml.exe的呢,我告訴你,在默認情況下操作系統只在當前目錄下尋找ml.exe,由於我們已將當前目錄切換為d:masm32in,而ml.exe就在此目錄下,所以你輸入ml(或者輸入ml.exe全名)並回車後,操作系統就在當前目錄下找ml.exe文件(註:當只輸入ml時,操作系統不僅僅是找擴展名為 .exe的文件,還包括.com、.bat等其他擴展名的可執行文件,有機會再介紹),找到後就調入內存並執行,如果找不到,操作系統就會去找一個叫做path的環境變數中去查詢,沿著path所列的目錄(叫路徑)來查找。如果在path所列的目錄中找到了目標文件,操作系統就會將該目標文件調入內存並執行;如果path所列的目錄都找了仍沒找到,操作系統就認為查找失敗,並在控制台窗口顯示沒找到目標文件的相關信息,結束本次命令的執行。

  真是這樣嗎?讓我們來檢驗一下。請您在控制台窗口輸入以下命令並執行:

  cd ..  回車 (註:將當前目錄切換到d:masm32)

  ml  回車 (註:執行ml.exe)

此時控制台窗口會顯示沒有找到ml.exe的相關信息。為什麼會出現這種情況?因為當前目錄下沒有ml.exe文件及以ml命名的其他可執行文件(如名為http://ml.com的文件和名為ml.bat的可執行文件等)。

  由上文介紹可知,我們寫一個彙編源代碼程序如果不放在ml.exe所在的目錄,用ml.exe彙編它還會遇到找不到ml.exe的困難,怎麼解決這個問題呢?當然有辦法,那就是配置環境變數path,讓環境變數包含ml.exe文件所在的目錄就可以了。

  好了,現在我介紹如何配置環境變數。有幾種方法:

  一是通過Windows桌面上[我的電腦]來配置。直接在Path最後面後加上;d:masm32in就可以了(紅色直接複製),具體可以參考配置java環境變數,詳情見鏈接(http://blog.csdn.net/u010043538/article/details/11869865)

  二是通過在控制台窗口輸入以下命令來配置:

  set path=d:masm32in;%path% 回車

這種方法有個缺點,就是每打開一次控制台窗口,就要重新配置一回,因為操作系統不保存用這種方法配置的結果。

  好了,現在控制台當前目錄還應該是d:masm32,你再輸入下面的指令試試:

  ml.exe

有了,ml.exe回顯的信息出現在屏幕上,說明本次環境變數配置成功,不管當前目錄是不是ml.exe所在的目錄,操作系統都能根據path找到ml.exe了。

 (5)編寫第一個彙編語言程序: hello.asm

  在沒有編寫程序之前,我們先在d:盤上建立一個名叫myasm的目錄,(不會使用DOS指令可以通過Windows的資源管理器創建),這個目錄就作為我們存放彙編語言開發項目的根目錄,在該目錄下再創建一個名為999的目錄,這個目錄就是我們放第一個彙編語言源代碼文件hello.asm的目錄。

  masm32不是一個功能完善的集成開發環境(即IDE),我用過的比較好點的集成開發環境是RadASM,但限於篇幅本文不介紹它。不管怎樣,彙編語言源代碼的編寫總是需要藉助文本編輯器的。文本編輯器有多種,其他我們暫都不用,有機會再說,現在我們就因陋就簡,使用Windows的記事本。請打開記事本,輸入下面的內容:

stack segment stack

byte 64 dup(0)

stack ends

data segment

msg byte hello world!$

data ends

code segment

assume cs:code,ss:stack,ds:data

start:

mov ax,data

mov ds,ax

mov dx,offset msg

mov ah,9

int 21h

mov ax,4c00h

int 21h

code ends

end start

(紅色部分為代碼,可直接複製)

  編輯完成後,將其保存名為hello.asm的文件,放在d:myasm999目錄下。這就是我們編寫的第一個彙編語言源程序。

(6)將hello.asm製作成可執行文件

  請回到控制台窗口,輸入以下指令:

  cd d:myasm999 回車 (註:將當前目錄切換到d:myasm999)

  dir 回車 (註:查看當前目錄下都有什麼子目錄和文件)

你應該從控制台窗口看到hello.asm文件在列表中。好,一切正常。

  我們現在要彙編hello.asm然後連接。在控制台窗口輸入以下指令:

  ml.exe /c hello.asm 回車 (注:此步為彙編)

  hello.asm中的內容如果無錯誤,您會在控制台窗口看到下面的信息:

D:myasm999&>ml /c hello.asm

Microsoft (R) Macro Assembler Version 6.14.8444

Copyright (C) Microsoft Corp 1981-1997. All rights reserved.

  Assembling: hello.asm

D:myasm999&>

這說明編譯成功。通過dir指令,你可以看到當前目錄下多了一個hello.obj文件,這就是剛彙編生成的中間文件。

  彙編成功了,第二步我們連接生成可執行文件。在命令行窗口輸入:

  link16 hello.obj,,,,, 回車 (註:5個逗號,用戶是默認運行。你也可以不打5個逗號,然後連續敲5個回車,這樣就會以默認名運行,讀者可不敲回車,根據提示,自己命名,建議採用默認)

  連接成功會在控制台窗口顯示以下信息:

D:myasm999&>link16 hello.obj,,,,,

Microsoft (R) Segmented Executable Linker Version 5.60.339 Dec 5 1994

Copyright (C) Microsoft Corp 1984-1993. All rights reserved.

D:myasm999&>

  通過在控制台窗口輸入dir命令,可以看到當前目錄下又多了一個名為 hello.exe的文件,它就是我們通過彙編、連接最終生成的可執行文件。在命令行窗口輸入命令執行它:

  hello.exe 回車 (註:執行hello.exe文件)

  再看控制台窗口,會出現以下信息:

D:myasm999&>hello.exe

hello world!

D:myasm999&>

這說明我們第一個入門程序開發成功了。

3.備註

以上內容主要參考於百度文庫,鏈接如下:http://wenku.baidu.com/view/4307b8f09e31433239689378.html。自己根據實際情況,做了少部分修改。

版權聲明:本文為博主原創文章,如需轉載,請註明地址:http://blog.csdn.net/sunkun2013 https://blog.csdn.net/u010043538/article/details/12720447

linux @不是油條

彙編語言入門一:環境準備

現階段,找個方便好使的編程環境還是比較蛋疼的,對於部分想過癮或者想從學習實踐中學習的小夥伴來說,略顯蛋疼。不過,仔細琢磨,還是能夠自己折騰出一個好用的環境來的。開搞。

環境

  • Ubuntu
  • gcc/nasm

也就是說,你先安裝一個能正常使用的Ubuntu再說吧,然後順便熟悉一些相關的概念和操作。

後面若沒有特殊說明,那我們討論的問題都是在這個軟體環境下。

環境檢查

先打開終端,安裝所需軟體(注意$開頭的才是命令,並且$並不屬於命令的一部分):

$ sudo apt-get install gcc nasm vim gcc-multilib -y

在終端中分別執行which nasm和which gcc,得到如下結果,則表示環境已經安裝完畢。

$ which nasm

/usr/bin/nasm

$ which gcc

/usr/bin/gcc

開始第一個程序

在彙編語言環境下,我們先別急著搞什麼Hello World,在這裡要列印出Hello World還不是一個簡單的事情,這也算是初入彙編比較讓人不解的地方,成天都在扯什麼寄存器定址啥的,說好的變數分支循環函數呢?

別說話,先按照我的套路把環境配好,程序跑起來了再說。注意,不是Hello World。先亮出第一個程序的C語言等價代碼:

int main() {

return 0;

}

不好意思,大括弧沒換行。你以為接下來我要gcc -S嗎?Too naive。我這可是正宗手工藝,非機械化生產。

說正事,先一股腦啥都不知道地把代碼敲完,跑起來再說:

首先準備個文件,暫且叫做first.asm吧,然後把下面的代碼搞進去:

global main

main:

mov eax, 0

ret

好了程序寫完了,你能感受到這裡的0就是上面C代碼里的0,說明你有學習彙編的天賦。

OK接下來就要編譯運行了。來一堆命令先:

$ nasm -f elf first.asm -o first.o

$ gcc -m32 first.o -o first

這下,程序就編譯好了,像這樣:

$ ls

first first.asm first.o

好了我們運行一下:

$ ./first ; echo $?

別問我為何上面的命令後面多了一串奇怪的代碼,你自己把它刪掉之後再看就能猜出來是幹啥的了。如果還有疑惑,可以再次做實驗確認,比如把代碼里的0改成1。變成這樣:

global main

main:

mov eax, 1

ret

再按照同樣的套路來編譯運行:

$ nasm -f elf first.asm -o first.o

$ gcc -m32 first.o -o first

$ ./first ; echo $?

1

OK,咱們的環境準備工作大功告成,後面再細說該怎麼搞事情(心情好的話還有ARM版的哦,準備好ARM環境或者買個樹莓派吧)。

編輯於 2017-11-27


其實windows支持直接運行以com為後綴名的文件,這樣的文件好像可以直接調用DOS中斷,並不用虛擬機。.com的文件就直接是純二進位,nasm好像用-f bin選項可以編譯出來。

另外nasm加上-f elf可以編譯出elf格式的文件,可以在Linux或WSL中執行。這個時候就要用Linux的API。masm不清楚。

補充:

新建一個.com文件,輸入中文「膻」,並運行,你會看到一個黑框框,這就是最簡單的.com文件。(不記得應該用ANSI還是utf-8編碼了,好像是ANSI)

用nasm編譯如下代碼:

org 0100h

jmp $;

即可得到這樣的一個文件

剛剛試了一下,windows10確實已經不行了,xp還可以。


謝邀,參見 @呂不鬧 ,我神教的GAS。


巧了,最近也在看彙編的資料。Windows 下的開發最高贊已經說的挺清楚的了(感謝),Linux 下可以看《Professional Assembly Language》 by Richard Blum,大約第三四章的位置,事無巨細地講解了開發中用到的工具,環境的搭建,以及對照示例代碼的詳細描述。


在虛擬機里安裝win2000,買本王爽的 《彙編語言》,對著做練習就可以了。這本書適合初學者看,裡面會教你怎麼debug,怎麼鏈接成可執行文件。至於為啥要win2000,是防止你因為裝環境搞半天。


可以參考GNU的inline assembly的形式,即在c語言中嵌入彙編代碼。


Win32/64位彙編知識(從實模式到保護模式那一套),C函數參數傳遞規則(如_stdcall,fastcall等)。如果要針對CPU優化,還得看Intel的軟體白皮書(好像是這個吧),Linux下不太清楚,本人只寫過Linux下樹莓派的彙編(渣渣水平) 逃。。。


linux下面的話,elf文件,還有linux的abi(calling convention, stack layout, ...)


推薦閱讀:

聯想為何要收購 IBM 的 X86 伺服器業務?
80686-Pentium Pro
x86寄存器使用的疑惑?
奔騰四採用的超線程技術與SNB之後的CPU採用的超線程技術是同一個技術嗎?
如何掌握Intel Intrinsic Instruction?

TAG:x86 | CC | 編譯器 |