什么是匯編語言
匯編語言(assembly language)是一種用于電子計算機、微處理器、微控制器或其他可編程器件的低級語言,亦稱為符號語言。在匯編語言中,用助記符(Mnemonics)代替機器指令的操作碼,用地址符號(Symbol)或標號(Label)代替指令或操作數(shù)的地址。在不同的設備中,匯編語言對應著不同的機器語言指令集,通過匯編過程轉換成機器指令。普遍地說,特定的匯編語言和特定的機器語言指令集是一一對應的,不同平臺之間不可直接移植。
許多匯編程序為程序開發(fā)、匯編控制、輔助調(diào)試提供了額外的支持機制。有的匯編語言編程工具經(jīng)常會提供宏,它們也被稱為宏匯編器。
匯編語言不像其他大多數(shù)的程序設計語言一樣被廣泛用于程序設計。在今天的實際應用中,它通常被應用在底層,硬件操作和高要求的程序優(yōu)化的場合。驅動程序、嵌入式操作系統(tǒng)和實時運行程序都需要匯編語言。
發(fā)展歷程
說到匯編語言的產(chǎn)生,首先要講一下機器語言。機器語言是機器指令的集合。機器指令展開來講就是一臺機器可以正確執(zhí)行的命令。電子計算機的機器指令是一列二進制數(shù)字。計算機將之轉變?yōu)橐涣懈叩碗娖?,以使計算機的電子器件受到驅動,進行運算。
上面所說的計算機指的是可以執(zhí)行機器指令,進行運算的機器。這是早期計算機的概念。在我們常用的PC機中,有一個芯片來完成上面所說的計算機的功能。這個芯片就是我們常說的CPU(Central Processing Unit,中央處理單元)。每一種微處理器,由于硬件設計和內(nèi)部結構的不同,就需要用不同的電平脈沖來控制,使它工作。所以每一種微處理器都有自己的機器指令集,也就是機器語言。CPU 只負責計算,本身不具備智能。你輸入一條指令(instruction),它就運行一次,然后停下來,等待下一條指令。這些指令都是二進制的,稱為操作碼(opcode),比如加法指令就是00000011。編譯器的作用,就是將高級語言寫好的程序,翻譯成一條條操作碼。對于人類來說,二進制程序是不可讀的,根本看不出來機器干了什么。為了解決可讀性的問題,以及偶爾的編輯需求,就誕生了匯編語言。匯編語言是二進制指令的文本形式,與指令是一一對應的關系。比如,加法指令00000011寫成匯編語言就是 ADD。只要還原成二進制,匯編語言就可以被 CPU 直接執(zhí)行,所以它是最底層的低級語言。
早期的程序設計均使用機器語言。程序員們將用0, 1數(shù)字編成的程序代碼打在紙帶或卡片上,1打孔,0不打孔,再將程序通過紙帶機或卡片機輸入計算機,進行運算。這樣的機器語言由純粹的0和1構成,十分復雜,不方便閱讀和修改,也容易產(chǎn)生錯誤。程序員們很快就發(fā)現(xiàn)了使用機器語言帶來的麻煩,它們難于辨別和記憶,給整個產(chǎn)業(yè)的發(fā)展帶來了障礙,于是匯編語言產(chǎn)生了。
匯編語言的主體是匯編指令。匯編指令和機器指令的差別在于指令的表示方法上。匯編指令是機器指令便于記憶的書寫格式。
操作:寄存器BX的內(nèi)容送到AX中
1000100111011000 機器指令
mov ax,bx 匯編指令
此后,程序員們就用匯編指令編寫源程序。可是,計算機能讀懂的只有機器指令,那么如何讓計算機執(zhí)行程序員用匯編指令編寫的程序呢?這時,就需要有一個能夠將匯編指令轉換成機器指令的翻譯程序,這樣的程序我們稱其為編譯器。程序員用匯編語言寫出源程序,再用匯編編譯器將其編譯為機器碼,由計算機最終執(zhí)行。
語言特點
匯編語言是直接面向處理器(Processor)的程序設計語言。處理器是在指令的控制下工作的,處理器可以識別的每一條指令稱為機器指令。每一種處理器都有自己可以識別的一整套指令,稱為指令集。處理器執(zhí)行指令時,根據(jù)不同的指令采取不同的動作,完成不同的功能,既可以改變自己內(nèi)部的工作狀態(tài),也能控制其它外圍電路的工作狀態(tài)。
匯編語言的另一個特點就是它所操作的對象不是具體的數(shù)據(jù),而是寄存器或者存儲器,也就是說它是直接和寄存器和存儲器打交道,這也是為什么匯編語言的執(zhí)行速度要比其它語言快,但同時這也使編程更加復雜,因為既然數(shù)據(jù)是存放在寄存器或存儲器中,那么必然就存在著尋址方式,也就是用什么方法找到所需要的數(shù)據(jù)。例如上面的例子,我們就不能像高級語言一樣直接使用數(shù)據(jù),而是先要從相應的寄存器AX、BX 中把數(shù)據(jù)取出。這也就增加了編程的復雜性,因為在高級語言中尋址這部分工作是由編譯系統(tǒng)來完成的,而在匯編語言中是由程序員自己來完成的,這無異增加了編程的復雜程度和程序的可讀性。
再者,匯編語言指令是機器指令的一種符號表示,而不同類型的CPU 有不同的機器指令系統(tǒng),也就有不同的匯編語言,所以,匯編語言程序與機器有著密切的關系。所以,除了同系列、不同型號CPU 之間的匯編語言程序有一定程度的可移植性之外,其它不同類型(如:小型機和微機等)CPU 之間的匯編語言程序是無法移植的,也就是說,匯編語言程序的通用性和可移植性要比高級語言程序低。
正因為匯編語言有“與機器相關性”的特性,程序員用匯編語言編寫程序時,可充分對機器內(nèi)部的各種資源進行合理的安排,讓它們始終處于最佳的使用狀態(tài)。這樣編寫出來的程序執(zhí)行代碼短、執(zhí)行速度快。匯編語言是各種編程語言中與硬件關系最密切、最直接的一種,在時間和空間的效率上也最高的一種。
總體特點
1.機器相關性
這是一種面向機器的低級語言,通常是為特定的計算機或系列計算機專門設計的。因為是機器指令的符號化表示,故不同的機器就有不同的匯編語言。使用匯編語言能面向機器并較好地發(fā)揮機器的特性,得到質(zhì)量較高的程序。
2.高速度和高效率
匯編語言保持了機器語言的優(yōu)點,具有直接和簡捷的特點,可有效地訪問、控制計算機的各種硬件設備,如磁盤、存儲器、CPU、I/O端口等,且占用內(nèi)存少,執(zhí)行速度快,是高效的程序設計語言。
3.編寫和調(diào)試的復雜性
由于是直接控制硬件,且簡單的任務也需要很多匯編語言語句,因此在進行程序設計時必須面面俱到,需要考慮到一切可能的問題,合理調(diào)配和使用各種軟、硬件資源。這樣,就不可避免地加重了程序員的負擔。與此相同,在程序調(diào)試時,一旦程序的運行出了問題,就很難發(fā)現(xiàn)。
優(yōu)點
1、因為用匯編語言設計的程序最終被轉換成機器指令,故能夠保持機器語言的一致性,直接、簡捷,并能像機器指令一樣訪問、控制計算機的各種硬件設備,如磁盤、存儲器、CPU、I/O端口等。使用匯編語言,可以訪問所有能夠被訪問的軟、硬件資源。
2、目標代碼簡短,占用內(nèi)存少,執(zhí)行速度快,是高效的程序設計語言,經(jīng)常與高級語言配合使用,以改善程序的執(zhí)行速度和效率,彌補高級語言在硬件控制方面的不足,應用十分廣泛。
缺點
1、匯編語言是面向機器的,處于整個計算機語言層次結構的底層,故被視為一種低級語言,通常是為特定的計算機或系列計算機專門設計的。不同的處理器有不同的匯編語言語法和編譯器,編譯的程序無法在不同的處理器上執(zhí)行,缺乏可移植性;
2、難于從匯編語言代碼上理解程序設計意圖,可維護性差,即使是完成簡單的工作也需要大量的匯編語言代碼,很容易產(chǎn)生bug,難于調(diào)試;
3、使用匯編語言必須對某種處理器非常了解,而且只能針對特定的體系結構和處理器進行優(yōu)化,開發(fā)效率很低,周期長且單調(diào)。
語言組成
數(shù)據(jù)傳送指令
這部分指令包括通用數(shù)據(jù)傳送指令MOV、條件傳送指令CMOVcc、堆棧操作指令PUSH/PUSHA/PUSHAD/POP/POPA/POPAD、交換指令XCHG/XLAT/BSWAP、地址或段描述符選擇子傳送指令LEA/LDS/LES/LFS/LGS/LSS等。注意,CMOVcc不是一條具體的指令,而是一個指令簇,包括大量的指令,用于根據(jù)EFLAGS寄存器的某些位狀態(tài)來決定是否執(zhí)行指定的傳送操作。
整數(shù)和邏輯運算指令
這部分指令用于執(zhí)行算術和邏輯運算,包括加法指令ADD/ADC、減法指令SUB/SBB、加一指令INC、減一指令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、算術左移指令SAL、算術右移指令SAR、循環(huán)左移指令ROL、循環(huán)右移指令ROR等。
位操作指令
這部分指令包括位測試指令BT、位測試并置位指令BTS、位測試并復位指令BTR、位測試并取反指令BTC、位向前掃描指令BSF、位向后掃描指令BSR等。
條件設置指令
這不是一條具體的指令,而是一個指令簇,包括大約30條指令,用于根據(jù)EFLAGS寄存器的某些位狀態(tài)來設置一個8位的寄存器或者內(nèi)存操作數(shù)。比如SETE/SETNE/SETGE等等。
控制轉移指令
這部分包括無條件轉移指令JMP、條件轉移指令Jcc/JCXZ、循環(huán)指令LOOP/LOOPE/LOOPNE、過程調(diào)用指令CALL、子過程返回指令RET、中斷指令INTn、INT3、INTO、IRET等。注意,Jcc是一個指令簇,包含了很多指令,用于根據(jù)EFLAGS寄存器的某些位狀態(tài)來決定是否轉移;INT n是軟中斷指令,n可以是0到255之間的數(shù),用于指示中斷向量號。
串操作指令
這部分指令用于對數(shù)據(jù)串進行操作,包括串傳送指令MOVS、串比較指令CMPS、串掃描指令SCANS、串加載指令LODS、串保存指令STOS,這些指令可以有選擇地使用REP/REPE/REPZ/REPNE和REPNZ的前綴以連續(xù)操作。
輸入輸出指令
這部分指令用于同外圍設備交換數(shù)據(jù),包括端口輸入指令IN/INS、端口輸出指令OUT/OUTS。
高級語言輔助指令
這部分指令為高級語言的編譯器提供方便,包括創(chuàng)建棧幀的指令ENTER和釋放棧幀的指令LEAVE。
控制和特權指令
這部分包括無操作指令NOP、停機指令HLT、等待指令WAIT/MWAIT、換碼指令ESC、總線封鎖指令LOCK、內(nèi)存范圍檢查指令BOUND、全局描述符表操作指令LGDT/SGDT、中斷描述符表操作指令LIDT/SIDT、局部描述符表操作指令LLDT/SLDT、描述符段界限值加載指令LSR、描述符訪問權讀取指令LAR、任務寄存器操作指令LTR/STR、請求特權級調(diào)整指令ARPL、任務切換標志清零指令CLTS、控制寄存器和調(diào)試寄存器數(shù)據(jù)傳送指令MOV、高速緩存控制指令INVD/WBINVD/INVLPG、型號相關寄存器讀取和寫入指令RDMSR/WRMSR、處理器信息獲取指令CPUID、時間戳讀取指令RDTSC等。
浮點和多媒體指令
這部分指令用于加速浮點數(shù)據(jù)的運算,以及用于加速多媒體數(shù)據(jù)處理的單指令多數(shù)據(jù)(SIMD及其擴展SSEx)指令。這部分指令數(shù)據(jù)非常龐大,無法一一列舉,請自行參考INTEL手冊。
虛擬機擴展指令
這部分指令包括INVEPT/INVVPID/VMCALL/VMCLEAR/VMLAUNCH/VMRESUME/VMPTRLD/VMPTRST/VMREAD/VMWRITE/VMXOFF/VMON等。
相關技術
匯編器
典型的現(xiàn)代匯編器(assembler)建造目標代碼,由解譯組語指令集的易記碼(mnemonics)到操作碼(OpCode),并解析符號名稱(symbolic names)成為存儲器地址以及其它的實體。使用符號參考是匯編器的一個重要特征,它可以節(jié)省修改程序后人工轉址的乏味耗時計算?;揪褪前褭C器碼變成一些字母而已,編譯的時候再把輸入的指令字母替換成為晦澀難懂機器碼。
編譯環(huán)境
用匯編語言等非機器語言書寫好的符號程序稱為源程序,匯編語言編譯器的作用是將源程序翻譯成目標程序。目標程序是機器語言程序,當它被安置在內(nèi)存的預定位置上后,就能被計算機的CPU處理和執(zhí)行。
匯編的調(diào)試環(huán)境總的來說比較少,也很少有非常好的編譯器。編譯器的選擇依賴于目標處理器的類型和具體的系統(tǒng)平臺。一般來說,功能良好的編譯器用起來應當非常方便,比如,應當可以自動整理格式、語法高亮顯示,集編譯、鏈接和調(diào)試為一體,方便實用。
對于廣泛使用的個人計算機來說,可以自由選擇的匯編語言編譯器有MASM、NASM、TASM、GAS、FASM、RADASM等,但大都不具備調(diào)試功能。如果是為了學習匯編語言,輕松匯編因為擁有一個完善的集成環(huán)境,是一款非常適合初學者的匯編編譯器。
發(fā)展前景
匯編語言是機器語言的助記符,相對于比枯燥的機器代碼易于讀寫、易于調(diào)試和修改,同時優(yōu)秀的匯編語言設計者經(jīng)過巧妙的設計,使得匯編語言匯編后的代碼比高級語言執(zhí)行速度更快,占內(nèi)存空間少等優(yōu)點,但匯編語言的運行速度和空間占用是針對高級語言并且需要巧妙設計,而且部分高級語言在編譯后代碼執(zhí)行效率同樣很高,所以此優(yōu)點慢慢弱化。而且在編寫復雜程序時具有明顯的局限性,匯編語言依賴于具體的機型,不能通用,也不能在不同機型之間移植。常說匯編語言是低級語言,并不是說匯編語言要被棄之,相反,匯編語言仍然是計算機(或微機)底層設計程序員必須了解的語言,在某些行業(yè)與領域,匯編是必不可少的,非它不可適用。只是,現(xiàn)在計算機最大的領域為IT軟件,也是我們常說的計算機應用軟件編程,在熟練的程序員手里,使用匯編語言編寫的程序,運行效率與性能比其它語言寫的程序相對提高,但是代價是需要更長的時間來優(yōu)化,如果對計算機原理及編程基礎不扎實,反而增加其開發(fā)難度,實在是得不償失,對比2010年前后的軟件開發(fā),已經(jīng)是市場化的軟件行業(yè),加上高級語言的優(yōu)秀與跨平臺,一個公司不可以讓一個團隊使用匯編語言來編寫所有的東西,花上幾倍甚至幾十倍的時間,不如使用其它語言來完成,只要最終結果不比匯編語言編寫的差太多,就能搶先一步完成,這是市場經(jīng)濟下的必然結果。
但是,迄今為止,還沒有程序員敢斷定匯編語言是不需要學的,同時,匯編語言(Assembly Language)是面向機器的程序設計語言,設計精湛的匯編程序員,部分已經(jīng)脫離軟件開發(fā),擠身于工業(yè)電子編程中。對于功能相對小巧但硬件對語言設計要求苛刻的行業(yè),如4位單片機,由于其容量及運算,此行業(yè)的電子工程師一般負責從開發(fā)設計電路及軟件控制,主要開發(fā)語言就是匯編,c語言使用只占極少部分,而電子開發(fā)工程師是千金難求,在一些工業(yè)公司,一個核心的電子工程師比其它任何職員待遇都高,對比起來,一般電子工程師待遇是程序員的十倍以上。這種情況是因為21世紀以來,學習匯編的人雖然也不少,但是真正能學到精通的卻不多,它相對于高級語言難學,難用,適用范圍小,雖然簡單,但是過于靈活,學習過高級語言的人去學習匯編比一開始學匯編的人難得多,但是學過匯編的人學習高級語言卻很容易,簡從繁易,繁從簡難。對于一個全面了解微機原理的程序員,匯編語言是必修語言。
實際應用
隨著現(xiàn)代軟件系統(tǒng)越來越龐大復雜,大量經(jīng)過了封裝的高級語言如C/C++,Pascal/Object Pascal也應運而生。這些新的語言使得程序員在開發(fā)過程中能夠更簡單,更有效率,使軟件開發(fā)人員得以應付快速的軟件開發(fā)的要求。而匯編語言由于其復雜性使得其適用領域逐步減小。但這并不意味著匯編已無用武之地。由于匯編更接近機器語言,能夠直接對硬件進行操作,生成的程序與其他的語言相比具有更高的運行速度,占用更小的內(nèi)存,因此在一些對于時效性要求很高的程序、許多大型程序的核心模塊以及工業(yè)控制方面大量應用。
歷史上,匯編語言曾經(jīng)是非常流行的程序設計語言之一。隨著軟件規(guī)模的增長,以及隨之而來的對軟件開發(fā)進度和效率的要求,高級語言逐漸取代了匯編語言。但即便如此,高級語言也不可能完全替代匯編語言的作用。就拿Linux內(nèi)核來講,雖然絕大部分代碼是用C語言編寫的,但仍然不可避免地在某些關鍵地方使用了匯編代碼。由于這部分代碼與硬件的關系非常密切,即使是C語言也會顯得力不從心,而匯編語言則能夠很好揚長避短,最大限度地發(fā)揮硬件的性能。
首先,匯編語言的大部分語句直接對應著機器指令,執(zhí)行速度快,效率高,代碼體積小,在那些存儲器容量有限,但需要快速和實時響應的場合比較有用,比如儀器儀表和工業(yè)控制設備中。
其次,在系統(tǒng)程序的核心部分,以及與系統(tǒng)硬件頻繁打交道的部分,可以使用匯編語言。比如操作系統(tǒng)的核心程序段、I/O接口電路的初始化程序、外部設備的低層驅動程序,以及頻繁調(diào)用的子程序、動態(tài)連接庫、某些高級繪圖程序、視頻游戲程序等等。
再次,匯編語言可以用于軟件的加密和解密、計算機病毒的分析和防治,以及程序的調(diào)試和錯誤分析等各個方面。
最后,通過學習匯編語言,能夠加深對計算機原理和操作系統(tǒng)等課程的理解。通過學習和使用匯編語言,能夠感知、體會和理解機器的邏輯功能,向上為理解各種軟件系統(tǒng)的原理,打下技術理論基礎;向下為掌握硬件系統(tǒng)的原理,打下實踐應用基礎。
附注:寄存器和內(nèi)存模型
學習匯編語言,首先必須了解兩個知識點:寄存器和內(nèi)存模型。
先來看寄存器。CPU 本身只負責運算,不負責儲存數(shù)據(jù)。數(shù)據(jù)一般都儲存在內(nèi)存之中,CPU 要用的時候就去內(nèi)存讀寫數(shù)據(jù)。但是,CPU 的運算速度遠高于內(nèi)存的讀寫速度,為了避免被拖慢,CPU 都自帶一級緩存和二級緩存?;旧希珻PU 緩存可以看作是讀寫速度較快的內(nèi)存。
但是,CPU 緩存還是不夠快,另外數(shù)據(jù)在緩存里面的地址是不固定的,CPU 每次讀寫都要尋址也會拖慢速度。因此,除了緩存之外,CPU 還自帶了寄存器(register),用來儲存最常用的數(shù)據(jù)。也就是說,那些最頻繁讀寫的數(shù)據(jù)(比如循環(huán)變量),都會放在寄存器里面,CPU 優(yōu)先讀寫寄存器,再由寄存器跟內(nèi)存交換數(shù)據(jù)。
相關文章
匯編語言系列之匯編實現(xiàn)各種碼制的轉換(思路詳解)
本文列出了十六進制轉二進制、十進制、ASCII碼及大小寫字母轉換的代碼,對匯編語言系列之實現(xiàn)各種碼制的轉換問題感興趣的朋友跟隨小編一起看看吧2021-11-11os_object_release Crash 排查記錄分析
這篇文章主要為大家介紹了os_object_release Crash 排查記錄分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11