1. 程式人生 > >深入理解計算機系統(3.1)------組合語言和機器語言

深入理解計算機系統(3.1)------組合語言和機器語言

  《深入理解計算機系統》第三章——程式的機器級表示。作者首先講解了彙編程式碼和機器程式碼的關係,闡述了彙編承上啟下的作用;接著從機器語言IA32著手,分別講述瞭如何儲存資料、如何訪問資料、如何完成運算以及如何進行跳轉。通過這些步驟,又告訴了我們分支語句、迴圈語句是怎麼完成的,函式呼叫、棧幀結構以及遞迴過程。最後能通過編譯器產生的彙編程式碼表示,我們要了解編譯器和它的優化能力,知道編譯器能為我們完成哪些工作。

  而這篇部落格我們將講解彙編和機器程式碼的關係。首先下面一張圖是C語言、組合語言以及翻譯過的機器語言,大家可以先有個大概的眼熟。

  

1、機器語言

  這系列部落格第一篇 Hello World是如何執行的

  我們就詳細講解了程式的編譯,一個C語言程式是經過編譯器變成彙編程式,然後通過彙編器變成機器程式碼,最後被計算機執行。

  計算機是不能直接識別我們所編寫的C程式或者Java程式的。它只能識別機器語言,而機器語言是用二進位制程式碼表示的計算機能直接識別和執行的一種機器指指令系統令的集合。

  早期計算機就是指可以執行機器指令,進行運算的機器。在我們常用的PC機中,有一個晶片,就是我們常說的CPU(Central Processing Unit,中央處理單元)可以完成前面所說的計算機的功能,但是每一種這樣的微處理器(CPU)由於硬體設計和內部結構的不同,就需要用不同的電平脈衝來控制,使它工作。所以每一種微處理器都有自己的機器指令集,也就是機器語言。

  早期的程式設計均使用機器語言。程式設計師們將用0, 1數字編成的程式程式碼打在紙帶或卡片上,1打孔,0不打孔,再將程式通過紙帶機或卡片機輸入計算機,進行運算。

  用機器語言編寫程式,程式設計人員要首先熟記所用計算機的全部指令程式碼和程式碼的涵義。手程式設計序時,程式設計師得自己處理每條指令和每一資料的儲存分配和輸入輸出,還得記住程式設計過程中每步所使用的工作單元處在何種狀態。這是一件十分繁瑣的工作。編寫程式花費的時間往往是實際執行時間的幾十倍或幾百倍,而且,編出的程式全是些0和1的指令程式碼,直觀性差,還容易出錯。

  那麼該怎麼辦呢?這時候組合語言便產生了。

  需要注意的是現在除了計算機生產廠家的專業人員外,一般是不需要學習機器語言了。

2、組合語言

  組合語言的主體是彙編指令。彙編指令和機器指令的差別在於指令的表示方法上,彙編指令是機器指令便於記憶的書寫格式

  比如下面將暫存器 BX 的內容傳送到 AX 上:

操作:暫存器BX的內容送到AX中
 
1000100111011000              機器指令
 
mov ax,bx                    彙編指令

  我們能很明顯的從上面兩條指令看出區別,彙編指令相對於機器指令是很容易記住的。

  可能有人會問,我們用匯編語言編寫程式,可是計算機只認識機器指令,那該怎麼辦?這時候就需要一個能將組合語言轉換成機器指令的工具,我們稱其為編譯器。程式設計師用匯編語言寫出原始碼,再用匯編編譯器將其編譯為機器碼,最後由計算機執行。

  

  組合語言是直接面向處理器(Processor)的程式設計語言。處理器是在指令的控制下工作的,處理器可以識別的每一條指令稱為機器指令。每一種處理器都有自己可以識別的一整套指令,稱為指令集。處理器執行指令時,根據不同的指令採取不同的動作,完成不同的功能,既可以改變自己內部的工作狀態,也能控制其它外圍電路的工作狀態。

   組合語言的另一個特點就是它所操作的物件不是具體的資料,而是暫存器或者儲存器,也就是說它是直接和暫存器和儲存器打交道,這也是為什麼組合語言的執行速度要比其它語言快,但同時這也使程式設計更加複雜,因為既然資料是存放在暫存器或儲存器中,那麼必然就存在著定址方式,也就是用什麼方法找到所需要的資料。例如上面的例子,我們就不能像高階語言一樣直接使用資料,而是先要從相應的暫存器AX、BX 中把資料取出。這也就增加了程式設計的複雜性,因為在高階語言中定址這部分工作是由編譯系統來完成的,而在組合語言中是由程式設計師自己來完成的,這無異增加了程式設計的複雜程度和程式的可讀性。

   再者,組合語言指令是機器指令的一種符號表示,而不同型別的CPU 有不同的機器指令系統,也就有不同的組合語言,所以,組合語言程式與機器有著密切的關係。所以,除了同系列、不同型號CPU 之間的組合語言程式有一定程度的可移植性之外,其它不同型別(如:小型機和微機等)CPU 之間的組合語言程式是無法移植的,也就是說,組合語言程式的通用性和可移植性要比高階語言程式低。

  總結起來就是三個特點:機器相關性、高速度和高效率、編寫和除錯複雜(相對於高階語言)。

3、高階語言

   前面的機器語言和組合語言我們都有一定了瞭解了,組合語言也是和機器語言一樣,都是直接對硬體進行操作,但是組合語言指令採用了英文縮寫的識別符號,更容易識別和記憶。但是說起來更容易識別和記憶,也只是相對於機器語言而言的。在實際程式設計中,組合語言源程式也是十分複雜和冗長的,這時候高階語言產生了。

  高階語言並不是指一種語言,而是包括很多程式語言,比如Java、C、C++、C#、python等等,是高度封裝的程式語言。高階語言與計算機的硬體結構和指令系統無關,它有更強的表達能力,可方便地表示資料的運算和程式的控制結構,能更好的描述各種演算法,而且容易學習掌握。但高階語言編譯生成的程式程式碼一般比用匯程式設計序語言設計的程式程式碼要長,執行的速度也慢。

  從最開始我們給出的一張圖也可以看出,C語言寫出的短短几行程式碼,翻譯成組合語言會多很多,更不用說變成機器語言了。

4、總結

  首先我要說明的是,我們不需要學會如何用機器語言,組合語言來進行程式設計,畢竟我們不是計算機生產廠家的專業人員。我們所要知道的是如何看懂組合語言就行了。因為在我們所編寫的高階語言,被翻譯成組合語言時,編譯器會自動進行一些優化處理,而這些處理如果我們不知道,就會造成程式上的錯誤,具體例項後面會詳細講到。

  下一篇部落格我們將講解一個簡單的彙編程式例項。