匯編語言(Assembly Language)是任何一種用于電子計算機、微處理器、微控制器或其他可編程器件的低級語言,亦稱為符號語言。在匯編語言中,用助記符代替機器指令的操作碼,用地址符號或標(biāo)號代替指令或操作數(shù)的地址。在不同的設(shè)備中,匯編語言對應(yīng)著不同的機器語言指令集,通過匯編過程轉(zhuǎn)換成機器指令。特定的匯編語言和特定的機器語言指令集是一一對應(yīng)的,不同平臺之間不可直接移植。
匯編語言,即第二代計算機語言,用一些容易理解和記憶的縮寫單詞來代替一些特定的指令,例如:用"ADD"代表加法操作指令,"SUB"代表減法操作指令,以及"INC"代表增加1,"DEC"代表減去1,"MOV"代表變量傳遞等等,通過這種方法,人們很容易去閱讀已經(jīng)完成的程序或者理解程序正在執(zhí)行的功能,對現(xiàn)有程序的bug修復(fù)以及運營維護都變得更加簡單方便。但計算機的硬件不認(rèn)識字母符號,這時候就需要一個專門的程序把這些字符變成計算機能夠識別的二進制數(shù)或機器語言。因為匯編語言只是將機器語言做了簡單編譯,所以并沒有根本上解決機器語言的特定性,所以匯編語言和機器自身的編程環(huán)境息息相關(guān),推廣和移植很難,但是還是保持了機器語言優(yōu)秀的執(zhí)行效率,因為他的可閱讀性和簡便性,匯編語言到現(xiàn)在依然是常用的編程語言之一。匯編語言不像其他大多數(shù)的程序設(shè)計語言一樣被廣泛用于程序設(shè)計。在今天的實際應(yīng)用中,它通常被應(yīng)用在底層,硬件操作和高要求的程序優(yōu)化的場合。驅(qū)動程序、嵌入式操作系統(tǒng)和實時運行程序都需要匯編語言。
自從1946年世界上第一臺電子計算機問世,人類和機器的交流方式和語言就成為了軟件工程師和計算機從業(yè)者的主要研究方向,更有效更簡便的編程語言成為了軟件工程師的新寵兒,伴隨著計算機的飛速發(fā)展,計算機的硬件升級速度也越來越快,對編程語言的要求也日益嚴(yán)格。在過去的幾十年,編程語言有了長足的發(fā)展,至今已經(jīng)有四代語言問世。大量的編程語言為了滿足不同領(lǐng)域的編程要求和軟件功能,經(jīng)歷了被修改,被取代,被發(fā)展等過程,最終發(fā)展成了現(xiàn)在編程語言的多樣化。盡管人們多次試圖尋找一個能夠適應(yīng)所有編程環(huán)境的通用語言,但是卻沒有一次成功。程序設(shè)計語言正在與現(xiàn)代科技日益飛躍,人類的智慧在日益彰顯。
計算機的硬件作為一種電路元件,它的輸出和輸入只能是有電或者沒電,也就是所說的高電平和低電平,所以計算機傳遞的數(shù)據(jù)是由“0”和“1”組成的二進制數(shù),所以說二進制的語言是計算機語言的本質(zhì)。計算機發(fā)明之初,人們?yōu)榱巳タ刂朴嬎銠C完成自己的任務(wù)或者項目,只能去編寫“0”、“1”這樣的二進制數(shù)字串去控制電腦,其實就是控制計算機硬件的高低電平或通路開路,這種語言就是機器語言。直觀上看,機器語言十分晦澀難懂,其中的含義往往要通過查表或者手冊才能理解,使用的時候非常痛苦,尤其當(dāng)你需要修改已經(jīng)完成的程序時,這種看起來無序的機器語言會讓你無從下手,也很難找到程序的錯誤。而且,不同計算機的運行環(huán)境不同,指令方式操作方式也不盡相同,所以當(dāng)你在這種機器語言就有了特定性,只能在特定的計算機上執(zhí)行,而一旦換了機器就需要重新編程,這極大的降低了程序的使用和推廣效率。但由于機器語言具有特定性,完美適配特定型號的計算機,故而運行效率遠(yuǎn)遠(yuǎn)高過其他語言。機器語言,也就是第一代編程語言。
不難看出機器語言作為一種編程語言,靈活性較差可閱讀性也很差,為了減輕機器語言帶給軟件工程師的不適應(yīng),人們對機器語言進行了升級和改進:用一些容易理解和記憶的字母,單詞來代替一個特定的指令。通過這種方法,人們很容易去閱讀已經(jīng)完成的程序或者理解程序正在執(zhí)行的功能,對現(xiàn)有程序的bug修復(fù)以及運營維護都變得更加簡單方便,這種語言就是我們所說的匯編語言,即第二代計算機語言。
比起機器語言,匯編語言具有更高的機器相關(guān)性,更加便于記憶和書寫,但又同時保留了機器語言高速度和高效率的特點。匯編語言仍是面向機器的語言,很難從其代碼上理解程序設(shè)計意圖,設(shè)計出來的程序不易被移植,故不像其他大多數(shù)的高級計算機語言一樣被廣泛應(yīng)用。所以在高級語言高度發(fā)展的今天,它通常被用在底層,通常是程序優(yōu)化或硬件操作的場合。
在編程語言經(jīng)歷了機器語言,匯編語言等更新之后,人們發(fā)現(xiàn)了限制程序推廣的關(guān)鍵因素——程序的可移植性。需要設(shè)計一個能夠不依賴于計算機硬件,能夠在不同機器上運行的程序。這樣可以免去很多編程的重復(fù)過程,提高效率,同時這種語言又要接近于數(shù)學(xué)語言或人的自然語言。在計算機還很稀缺的50年代,誕生了第一個高級編程語言。當(dāng)時計算機的造價不菲,但是每天的計算量又有限,如何有效的利用計算機有限的計算能力成為了當(dāng)時人們面對的問題。同時,因為資源的稀缺,計算機的運行效率也成為了那個年代工程師追尋的目標(biāo)。為了更高效的使用計算機,人們設(shè)計出了高級編程語言,來滿足人們對于高效簡潔的編程語言的追求。
由于匯編指令系統(tǒng)龐大,因而需構(gòu)建指令系統(tǒng)體系,其指令數(shù)量龐大,格式復(fù)雜,可記憶性差等。指令中最難的是指令所支持的尋址方式,其實質(zhì)就是指令中操作數(shù)如何獲取。對于處理器而言,就是如何找到他所需的數(shù)據(jù)。但對于計算機底層的匯編語言而言,這種尋址方式將涉及大量的計算存儲格式,與復(fù)雜的存儲管理方式緊密相關(guān),因而難以理解。最后,匯編指令還關(guān)系到如何影響標(biāo)志位,但處理器標(biāo)志位非常復(fù)雜,因而對其機制掌握就比較困難。
包括通用數(shù)據(jù)傳送指令MOV、條件傳送指令CMOVcc、堆棧操作指令PUSH/PUSHA/PUSHAD/POP/POPA/POPAD、交換指令XCHG/XLAT/BSWAP、地址或段描述符選擇子傳送指令LEA/LDS/LES/LFS/LGS/LSS等。
這部分指令用于執(zhí)行算術(shù)和邏輯運算,包括加法指令A(yù)DD/ADC、減法指令SUB/SBB、加一指令I(lǐng)NC、減一指令DEC、比較操作指令CMP、乘法指令MUL/IMUL、除法指令DIV/IDIV、符號擴展指令CBW/CWDE/CDQE、十進制調(diào)整指令DAA/DAS/AAA/AAS、邏輯運算指令NOT/AND/OR/XOR/TEST等。
這部分指令用于將寄存器或內(nèi)存操作數(shù)移動指定的次數(shù)。包括邏輯左移指令SHL、邏輯右移指令SHR、算術(shù)左移指令SAL、算術(shù)右移指令SAR、循環(huán)左移指令ROL、循環(huán)右移指令ROR等。
這部分指令包括位測試指令BT、位測試并置位指令BTS、位測試并復(fù)位指令BTR、位測試并取反指令BTC、位向前掃描指令BSF、位向后掃描指令BSR等。
這部分包括無條件轉(zhuǎn)移指令JMP、條件轉(zhuǎn)移指令JCC/JCXZ、循環(huán)指令LOOP/LOOPE/LOOPNE、過程調(diào)用指令CALL、子過程返回指令RET、中斷指令I(lǐng)NTn、INT3、INTO、IRET等。
這部分指令用于對數(shù)據(jù)串進行操作,包括串傳送指令MOVS、串比較指令CMPS、串掃描指令SCANS、串加載指令LODS、串保存指令STOS,這些指令可以有選擇地使用REP/REPE/REPZ/REPNE和REPNZ的前綴以連續(xù)操作。
這部分指令用于同外圍設(shè)備交換數(shù)據(jù),包括端口輸入指令I(lǐng)N/INS、端口輸出指令OUT/OUTS。
匯編語言是計算機提供給用戶的最快最有效的語言,也是能夠利用計算機的所有硬件特性并能夠直接控制硬件的唯一語言。但是由于編寫和調(diào)試匯編語言程序要比高級語言復(fù)雜,因此目前其應(yīng)用不如高級語言廣泛。
匯編語言比機器語言的可讀性要好,但跟高級語言比較而言,可讀性還是較差。不過采用它編寫的程序具有存儲空間占用少、執(zhí)行速度快的特點,這些是高級語言所無法取代的。在實際應(yīng)用中,是否使用匯編語言,取決于具體應(yīng)用要求、開發(fā)時間和質(zhì)量等方面作權(quán)衡。
匯編語言作為機器語言之上的第二代編程語言,它也有很多優(yōu)點:
可以輕松的讀取存儲器狀態(tài)以及硬件I/O接口情況
編寫的代碼因為少了很多編譯的環(huán)節(jié),可以能夠準(zhǔn)確的被執(zhí)行
作為一種低級語言,可擴展性很高
因為代碼非常單調(diào),特殊指令字符很少,所以造成了代碼的冗長以及編寫的困難
因為匯編仍然需要自己去調(diào)用存儲器存儲數(shù)據(jù),很容易出現(xiàn)BUG,而且調(diào)試起來也不容易
就算完成了一個程序,后期維護時候也需要耗費大量的時間。
因為機器的特殊性造成了代碼兼容性差的缺陷。
匯編語言的特點是容易被計算機識別和執(zhí)行,使用它進行編程可以減少占用空間、提高運行速度,并能直接對硬件實施控制。在需要實時控制的時候,有著不可替代的重要地位,但匯編語言在編程和理解時要復(fù)雜、困難一些,尤其是在進行數(shù)據(jù)處理或是邏輯運算時更加凸顯出其劣勢。
高級語言是面向使用者的語言,能更準(zhǔn)確地被程序員所理解,它的表達能力強,功能多,編程效率高,上手速度快,自動化程度高,因而更受歡迎。在大部分軟件開發(fā)中,使用者都采用高級語言編程,以提高編程效率。但在要求存儲空間小,執(zhí)行速度快,需直接對硬件進行控制的場合,則應(yīng)用匯編語言編程,以達到優(yōu)化程序速度的目的。
這樣兩種看似差別很大的語言,它們之間又有著緊密的聯(lián)系。在一些程序設(shè)計當(dāng)中,如果把兩者結(jié)合起來使用,將兩種語言的優(yōu)勢同時發(fā)揮出來,則可以解決很多特性難題。在許多程序的設(shè)計當(dāng)中,高級語言和匯編語言可以相互交叉調(diào)用,進行參數(shù)傳遞,共享數(shù)據(jù)信息,這便是所謂的混合編程。程序員往往在高級語言程序中直接嵌入?yún)R編語句,以實現(xiàn)對硬件直接進行控制的功能,這是混合編程中常見的做法。也可以在高級語言程序中使用匯編語言中定義的變量和常量,或使用內(nèi)部函數(shù)對匯編語句進行調(diào)用。簡而言之,這類混合編程的方法可以讓高級語言與匯編語言互相取長補短,各自發(fā)揮各自優(yōu)勢,同時減少各自缺點所帶來的不便,善用這個方法可以使開發(fā)和編程工作達到事半功倍的效果。
典型的現(xiàn)代匯編器(Assembler)建造目標(biāo)代碼,由解譯組語指令集的易記碼(Mnemonics)到操作碼(OpCode),并解析符號名稱(Symbolic Names)成為存儲器地址以及其它的實體。使用符號參考是匯編器的一個重要特征,它可以節(jié)省修改程序后人工轉(zhuǎn)址的乏味耗時計算?;揪褪前褭C器碼變成一些字母而已,編譯的時候再把輸入的指令字母替換成為晦澀難懂機器碼。
用匯編語言等非機器語言書寫好的符號程序稱為源程序,匯編語言編譯器的作用是將源程序翻譯成目標(biāo)程序。目標(biāo)程序是機器語言程序,當(dāng)它被安置在內(nèi)存的預(yù)定位置上后,就能被計算機的CPU處理和執(zhí)行。
匯編的調(diào)試環(huán)境總的來說比較少,也很少有非常好的編譯器。編譯器的選擇依賴于目標(biāo)處理器的類型和具體的系統(tǒng)平臺。一般來說,功能良好的編譯器用起來應(yīng)當(dāng)非常方便,比如,應(yīng)當(dāng)可以自動整理格式、語法高亮顯示,集編譯、鏈接和調(diào)試為一體,方便實用。
對于廣泛使用的個人計算機來說,可以自由選擇的匯編語言編譯器有MASM、NASM、TASM、GAS、FASM、RADASM等,但大都不具備調(diào)試功能。如果是為了學(xué)習(xí)匯編語言,輕松匯編因為擁有一個完善的集成環(huán)境,是一款非常適合初學(xué)者的匯編編譯器。
隨著現(xiàn)代軟件系統(tǒng)越來越龐大復(fù)雜,大量經(jīng)過了封裝的高級語言如C/C++,Pascal/Object Pascal也應(yīng)運而生。這些新的語言使得程序員在開發(fā)過程中能夠更簡單,更有效率,使軟件開發(fā)人員得以應(yīng)付快速的軟件開發(fā)的要求。而匯編語言由于其復(fù)雜性使得其適用領(lǐng)域逐步減小。但這并不意味著匯編已無用武之地。由于匯編更接近機器語言,能夠直接對硬件進行操作,生成的程序與其他的語言相比具有更高的運行速度,占用更小的內(nèi)存,因此在一些對于時效性要求很高的程序、許多大型程序的核心模塊以及工業(yè)控制方面大量應(yīng)用。
雖然隨著半導(dǎo)體技術(shù)、編程技術(shù)的不斷發(fā)展,在實際工程應(yīng)用中確實很少看到匯編語言的身影,但這并不能說明匯編語言沒用,已被其他高級語言所取代。嵌入式系統(tǒng)的底層驅(qū)動、計算機的BIOS還是要用匯編語言實現(xiàn)。匯編語言是培養(yǎng)學(xué)生理解硬件資源的語言,是學(xué)習(xí)和理解其他高級程序設(shè)計語言的基礎(chǔ),是計算機組成原理、接口與通信技術(shù)、計算機控制技術(shù)和數(shù)據(jù)采集等許多專業(yè)課的前導(dǎo)課程,是必要的基礎(chǔ)知識,起著承上啟下的作用。