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

語言: CN / TW / HK

《深入理解計算機系統》第三章——程序的機器級表示。作者首先講解了彙編代碼和機器代碼的關係,闡述了彙編承上啟下的作用;接着從機器語言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、總結

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

下一篇博客我們將講解一個簡單的彙編程序實例。