組合語言初探
一、什麼是組合語言
組合語言是(英語:Assembly Language)是一種用於電子計算機、微處理器、微控制器、或其他可程式設計器件的低階語言。
這是維基百科上對組合語言的解釋。其實組合語言與常見的 C、C++、Java 等語言一樣,都用來 “ 指揮 ” 計算機完成某項工作。只不過組合語言是直接在硬體上執行的一種程式語言,像 C、C++、Java 等高階語言最終也會被 “ 翻譯 ” 成組合語言。
二、為什麼要學習組合語言
組合語言是人和計算機溝通 最直接的方式 ,它描述了最終計算機所要執行的指令序列的意義。當你和一個會說八國語言的人交流時,最有效的方式還是和他用母語交流。這個比喻好像有點牽強,但是中心思想就是: 通過學習組合語言我們可以更加深入的理解計算機的工作方式 。
學習彙編還有一個好處,那就是能體驗到底層程式設計所帶來的樂趣。
我目前使用的是 Java 語言進行一些開發,都知道 Java 語言是跨平臺的,一個 java 檔案(原始碼)如下:
public class demo { public static void main(String[] args) { int a = 1; a = 6; for (int i = 0; i < a; i++) { a++; } } }
該檔案首先被編譯成 class 檔案(位元組碼),再將 class 檔案送入 JVM 中執行。JVM 再將 class 檔案中的位元組碼翻譯成對應平臺的機器碼。下面貼出這個 class 檔案 反彙編 後(使用 javap 命令)得到的彙編程式碼。
雖然這些彙編指令是 JVM 中特有的,但是應用起來和一般微處理器的彙編指令都是相通的。
都說深入 JVM 是一個 Java 高階工程師的必經之路,在我看來知識都是一步一步積累起來的,任何跳躍式的學習都是不靠譜的,讓一個連組合語言都不會的人直接去學習 JVM 相關的知識,效果可想而知。
綜合這些因素,我開啟了組合語言的學習之路。在我的學習過程中,主要的參考書籍是王爽教授的 ofollow,noindex"> 組合語言 這本書。
三、組合語言基礎知識
(一)機器語言
裸機的概念都知道,指的是沒有裝配任何作業系統和其他軟體的電子計算機。裸機唯一能識別的就是機器語言,就像一個沒有接受過教育的人,他還是會用語言表達一件事一樣(貌似又是一個糟糕的比喻 - - ! )。
機器語言是機器指令的集合,一臺電子計算機的機器指令是一系列二進位制序列。計算機將這些二進位制轉換成相應的高低電平,使計算機的電子器件收到 驅動 ,從而進行一些計算。
(二)組合語言與 CPU
在計算機中進行計算的功能由 CPU 來完成,每種 CPU 由於硬體設計和內部結構的不同,其機器指令也不相同,每種 CPU 都有屬於自己的 機器指令集 。
由於機器指令是一些二進位制序列,所以對於程式的編寫和修改是十分不方便的。因此就誕生了組合語言,學習一個新概念一定要知道他的來源,顯然組合語言就是由機器語言直接發展而來,產生的原因就是機器語言二進位制形式閱讀和書寫上的各種不便。
所以學習組合語言就是在學習機器語言,學習機器語言就是在學習與一個特定 CPU 打交道的方式。只不過組合語言更加的便於記憶和書寫罷了。
- 操作:暫存器 BX 的內容送到 AX 中
- 機器指令:1000100111011000
- 彙編指令:mov ax,bx
既然 CPU 只能識別二進位制序列,那麼計算機中必然有一個程式能將組合語言轉換成機器語言,這個程式就叫做彙編編譯器。針對不同的 CPU,有不同的 彙編編譯器 ,那麼問題來了,第一個彙編編譯器是用什麼寫的呢?答案應該是機器語言。
組合語言由下列 3 中指令構成:
- 彙編指令:機器指令的助記符,與機器指令一一對應
- 偽指令:沒有對應的機器指令,由編譯器執行,計算機並不執行(?)
- 其他符號:沒有對應的機器指令,如+、-、*、/等符號
上面說到了 CPU,CPU 是計算機中的核心部件,它是一個強大的計算中心。就拿簡單的 1 + 2 這個操作來說,要讓 CPU 執行這個操作,首先要讓 CPU 知道需要執行的是加法操作(指令),然後需要讓 CPU 知道讓哪兩個數相加(資料)。指令和資料在儲存器(儲存器的概念在下面說明)中存放。
其實程式和資料在儲存器中存放的形式都是一些二進位制序列 。 CPU 既能將這些序列看成資料,又能看成指令 ,就像 1000100111011000,如果 CPU 將其看作資料,這個數的大小就是 89D8H,如果將其看作指令,這個指令就是 mov ax,bx。
(三)儲存器
儲存器分為:
- 隨機儲存器(RAM)
- 只讀儲存器(ROM)
其實這兩個概念我以前也知道,但也就僅限於概念上的瞭解。但是在看完組合語言的第 1 章後, 我才知道儲存器還有物理意義上的儲存器和邏輯意義上的儲存器的區別 。
在介紹各種儲存器之前先了解一下主機板的概念。
一臺計算機中的主機板一般長這樣:
一眼就能看到 CPU 所在的位置和一些黃色的插槽,插槽上可以插各類介面卡(如顯示卡、網絡卡、記憶體卡等)。
具體說來,物理意義上的儲存器分為 RAM(讀寫) 和 ROM(只讀)。
其中記憶體卡全是 RAM,網絡卡和顯示卡中有 ROM,ROM 中一般裝有 BIOS ,它利用對應的硬體進行最基本的輸入輸出。而顯示卡中也有 RAM,顯示卡中的 RAM 就是指的 視訊記憶體 。顯示卡會隨時將視訊記憶體中的資料向顯示器輸出。
上面說的是物理意義上的儲存器,那什麼是邏輯意義上的儲存器呢?
邏輯意義上的儲存器的概念是針對於 CPU 而言的,CPU 將各種 RAM 和 ROM 看成是一個同一的整體,通過 地址匯流排 進行定址, CPU 把這些 RAM 和 ROM 統一的當做記憶體對待 。
(四)記憶體地址空間
在計算機中,所有的物理儲存器被看作一個由若干儲存單元組成的邏輯儲存器。 這個邏輯儲存器所在的空間被稱為記憶體地址空間 。
記憶體地址空間的大小受 CPU 地址匯流排寬度的限制。 8086CPU 的地址匯流排寬度為 20,那麼它就能定址 2 20 個地址單元,即 1MB。所以當你使用 8086CPU 時,即使給它配上 1G 的記憶體卡,它最多能使用到的記憶體單元也只有 1MB。
下面是 8086CPU 記憶體地址空間的分配情況:
從地址 0 ~ 9FFFF 的記憶體單元讀取資料,實際就是在讀取主隨機儲存器的資料;向地址 A0000 ~ BFFFF 的記憶體單元中寫資料,就是想視訊記憶體中寫入資料,這些資料會被顯示卡輸出到顯示器上;向 C0000 ~ FFFFF 的記憶體單元中寫入資料是無效的,因為這一段地址空間是隻讀的。
四、總結
《組合語言》的第一章主要是介紹了一些計算機硬體基礎知識,為下面兩張對暫存器的學習做了很好的鋪墊。王爽教授的這本書真的挺不錯,短短的一章內容就足以讓我有了很強的閱讀慾望,期待下面兩章對暫存器的閱讀。
(完)