1. 程式人生 > >彙編第9~15章——彙編基礎知識梳理與總結

彙編第9~15章——彙編基礎知識梳理與總結

第9章
本章講轉移指令,書中說:

可以修改IP,或同時修改CS和IP的指令統稱為轉移指令

轉移指令根據轉移時是否修改CS分為段內轉移和段間轉移。

最值得注意的一點,以段內轉移為例,如jmp s0指令,轉換為機器碼後佔用兩個位元組,第一個位元組是jmp指令自己的機器碼,而第二位元組尤其重要,它是轉移目標指令相對於jmp的下一條指令的偏移距離。

為什麼會這麼設計呢?簡單回顧一下指令的執行過程:

CPU從CS:IP指向的地址中讀取指令
IP指向下一條指令
執行指令
因為IP暫存器總是在讀取指令後就更改為當前指令的下一條指令的地址了,而此時當前指令還沒有執行,當控制器執行jmp指令時,只需要將IP中的值加上第二個位元組中的偏移距離,就可以找到跳轉的目標指令的地址了。

而這個特點在本書實驗8中得以體現,可以說分析完實驗8才真正意義上讓我記住了jmp指令的特點。

關於實驗9
實驗9通過介紹記憶體中的顯示緩衝區,讓我對計算機是如何將輸入輸出列印在螢幕上有了更深的認識,因為我知道現代計算機的顯示通常是通過顯示卡完成的,而顯示卡中有一塊記憶體區域就對應到顯示器的顯示內容。顯然在很早以前8086就通過這種規定記憶體中一塊區域對應顯示內容來實現了資料的輸出顯示。

第10章
本章通過call和ret指令引入了子程式的概念,同時也不得不開始使用棧,因為在程式的反覆呼叫中必然涉及到暫存器不夠用的問題,如果不使用棧,不論是子程式還是多重迴圈,都會破壞暫存器中原有的值,使得整個程式發生錯誤。

所以說棧的設計真的很精妙,它使程式設計師能用更大容量的記憶體儲存暫存器值,以達到整個計算機只需要少量暫存器就可以完成規模龐大的複雜演算法的目的。

第11章
本章講標誌暫存器,在學習本章之前,我對標誌暫存器的認識也僅僅停留在“知道有這麼個東西,但是具體都是啥並不清楚”的程度。

CF標誌暫存器
其中讓我覺得最巧妙的設計是進位(借位)標誌位CF,如果在上一次運算中產生了進位(或借位)CF就為1,否則為0。和它相關的還有一個指令是 adc 指令,如 adc ax,1 這條指令,執行後相當於ax = ax + 1 + CF。在我初看到這裡時並不理解這樣做的意義是什麼,直到後文中通過adc命令完成了32位加法時我才霍然開朗。也就是說:

CF標誌和adc指令共同作用,使得16位暫存器系統中能夠完成32位,64位甚至1024位的加法運算。

與adc指令類似的還有sbb,它同樣利用CF的借位資訊完成多位數的減法運算。

CMP指令
另外本章根據zf,cf等標誌位引入了CMP指令,至此一個能夠完成複雜演算法的包括順序結構、分支結構、迴圈結構的程式終於完整了。

第12~13章
內中斷,也就是現代作業系統概念中的異常。由於前段時間剛通過《深入理解Linux核心》和網路等途徑理解過一次中斷,所以對本書中提到的中斷的概念都在學習前就有了大概認識。

通過這兩章自己動手編寫中斷例程並安裝中斷,更清楚了在電腦加電的那一剎那,BIOS是如何配置中斷向量表,載入中斷例程,再將控制權交給作業系統的。

另外,一些保留的中斷號,使用者是可以通過程式設計來新增中斷例程的,這也使我隨之想到了現代作業系統中各種許可權的限制的必要性。

第14章
本章主要知識點總結如下:

在DOS系統中,所有的外設都有專屬的一個或多個埠號,CPU通過埠號對外設進行讀寫操作。
同一外設可能因為操作需要有多個埠號,比如CMOS RAM晶片,70h埠用於寫入需要訪問的資料地址,71h埠根據70h埠提供的地址取出資料。
訪問埠資料只需使用 in 和 out 兩條指令
第15章
本章主要講外中斷,記憶體中通過特定記憶體單元儲存鍵盤的狀態位元組,通過該位元組判斷鍵盤中Ctrl、Shift、Capslock等控制和切換鍵的狀態

也就是說,我們在每次使用鍵盤輸入的時候,如果是字元鍵,作業系統首先會讀入掃描碼,然後檢測鍵盤的狀態位元組,看是否有切換鍵按下,根據切換鍵選擇字元鍵對應的ASCII碼寫入鍵盤的緩衝區。