這個總結先在wps上已經寫完放很久了。之前由於考試,沒來得及放上來。現在一次性都放上來吧~
剛看完彙編,由於是借學校的書,所以就把關鍵知識點寫在博客上了.
參考的是richard blum的<彙編語言程序設計>,看豆瓣上面分數蠻高的.
主要平臺是linux下的AT&T彙編..
我學彙編主要是想可以看懂彙編代碼的意思.其實所謂優化也不過是調調代碼順序,用點比較特殊的指令,如果不是很有經驗的話,可能人來優化的還不如編譯器..
我就把彙編當作以後學新語言瞭解編譯器在幹什麼的一個工具就可以了.
嗯...下面說正文
第一部分主要說明的是對彙編的介紹和編譯調試,所以我就簡單介紹一下.重點在編譯和調試
計算機是如何執行程序的?
第一章一開始就提到了,程序是純二進制的.是CPU通過時序邏輯將二進制的高低電平讀入,然後根據二進制碼來執行相關操作的.這裏的指令碼格式學過計算機組成原理的估計就可以不用說了吧.簡單來說就是指令的一部分是操作的編碼,一部分是數的編碼.
這裏提到一點比較重要,就是指令前綴(操作的編碼一部分)的鎖定前綴.原來還疑惑多處理器是怎麼做到對共享內存區的原子操作的,現在來看就是這裏的原因了.CPU已經提供了這種多CPU共享內存的保障.(幾個月後,看了Linux源碼,發現原來自己接觸過這個東西...所有鎖都是用的這個方式,鎖定總線)
程序是如何生成可執行文件的?
順帶講一講,很多大學生學C的時候都忽略了的.估計用微軟IDE編程的人都可能不太清楚(比如說我...).但是在linux下的話就很清楚了.其實編譯器在編譯你的源文件的時候是先生成目標代碼文件再通過連接器將目標代碼連接起來生成可執行文件的.如果所用到的目標代碼文件是共享的話,還有動態鏈接這個東西,當然我們如果沒做過大項目的話,應該用的都是靜態連接.即把程序一次性全部都放到內存.動態連接則是一部分一部分的連接.
彙編程序的組成有哪些?
1.數據段
2.Bss段
3.文本段(代碼段)
數據段和bss段都是用來存放數據的區域.
文本段就是代碼段,就是你自己寫的代碼.
注意,其實對於gcc有時候並不是將bss段當作存放全局變量的區域.而是放在.data段中.
百度的解釋是:BSS存放的是未初始化的全局變量和靜態變量,數據段存放的是初始化後的全局變量和靜態變量。
實際上我在linux下測試之後發現,全局變量聲明的時候是用的.comm聲明的,並且沒有看到.bss的聲明。我想現在的彙編器應該默認會是.bss段了吧。
彙編語言有標準嗎?
彙編語言實際上是沒有標準的.基本根據彙編器來.所有你寫的都是助記符,也就是mov,sub之類的都是彙編器提供的.所以彙編器就很重要.很多高級語言的特性都依賴於彙編器的命令.
(幾個月後來看也不能說沒有標準,默認的都會支持基本的C編譯需要的指令)
Intel和AT&T彙編差別大嗎?
由於之前怕難,就學了16位彙編,現在看intel彙編和AT&T彙編差別也不是太大..只是AT&T彙編編寫比intel的繁瑣一些.,絕大部分都是相似的.資料方面也基本相同.linux有這麼方便的開源優勢.建議初學者直接選AT&T.而且還能熟悉gdb調試,這對之後調試其他語言都是有經驗累積的.當然你說你只想在windows下編程那還是去學intel的吧.
CPU是順序執行你程序裏的二進制代碼嗎?
這個我之前也覺得除了cache可以緩存一下其他沒什麼.但是學了彙編才知道intel還真是很NB啊..除了緩存還有
1.指令的預取和解碼(計算機組成原理裏面的流水線技術?)
2.分支預測
這個很NB啊,可以根據你運行的if ,switch各個單元選中的概率來預讀.
當然還有函數調用和循環這之類的跳轉指令的優化.
主要包括3種技術
深度分支預測
動態數據流分析
推理行執行(感覺個個都是碉堡的節奏啊...)
3.亂序執行引擎
這個東西一聽名字好奇怪,但其實就是通過幾個緩衝區,來改變指令的順序.讓指令更快的執行
4.退役單元
就是接手亂序執行引擎送出來指令送去執行,然後監視執行的情況.並且將指令調整到正確的順序..(高端技術..只能瞭解瞭解..)
通用寄存器有哪些?
寄存器簡單的來說就是CPU中存儲處理數據的一個小的觸發器(數電的內容啊!),速度很快,所以用於指令的操作(指令絕大部分都要用到寄存器的,也有簡單的指令不用.比如nop)
EAX |
操作數和結果數據的累加器 |
EBX |
指向數據內存段中的數據的指針 |
ECX |
字符串和循環操作的計數器 |
EDX |
I/O指針 |
EDI |
用於字符串操作的目標的數據指針 |
ESI |
用於字符串操作的源的數據指針 |
ESP |
堆棧指針 |
EBP |
堆棧數據指針 |
敲了一遍回憶了好久後面的知識點..寫總結還是得多寫啊.
通過段寄存器訪問系統內存的方式有哪些?
這個不是組成原理裏面的一大堆尋址方式..而是內存使用的方式...組成原理中尋址方式是針對彙編指令的。
1.平坦內存模式
2.分段內存模式
3.實地址模式
平坦內存模式:就是將所有內存都看成線性連續的地址空間.即段基址爲0..主流操作系統都是這個模式.
分段內存模式:就是操作系統課程裏面的,按邏輯來給指令分段.順帶一說,教科書真的是該看國外的啊.我課本上面還寫着分頁式管理內存空間的操作系統不能動態連接..其實linux就是分頁式的操作系統,一樣可以實現動態連接.操作系統實現基本都是靠的設計者編碼..哪有不能的呢?只有想不到的.
不過單就彙編的話,這些寄存器應該多用於控制堆棧空間.也就是保存數據的地方,然後通過偏移量+堆棧基址指針的方式來找到對應的變量存儲位置.順帶一說AT&T的堆棧空間貌似都是從高地址開始向低地址延伸的.所以偏移量通常爲負數
實地址模式:所有段寄存器都指向零線性地址,並且都不會被程序改動.所有指令碼,數據元素和堆棧元素都是通過他們的線性地址直接訪問的.或者還是存放C語言中常量字符串的地方?這個零線性地址google和百度都沒有搜索相關結果.(幾個月後來看,感覺實地址模式只是存在於8086中的..感覺翻譯也有問題.)
CS |
代碼段 |
DS |
數據段 |
SS |
堆棧段 |
ES |
附加段指針 |
FS |
附加段指針 |
GS |
附加段指針 |
什麼是指令指針寄存器?
其實就是計算機組成原理裏面的PC寄存器,每次將所指向的指令取出來執行.如果要預取的話就不是線性的取了..不過一般不用管這個.一般和CS+EIP就是所指向的位置.CS是段位置
EIP是偏移量.
什麼是控制寄存器?
用於確定處理器的操作模式.這估計只有寫操作系統的人才用得到的吧
CR0 |
控制操作模式和處理器狀態的系統標誌 |
CR1 |
當前沒有使用 |
CR2 |
內存頁面錯誤信息 |
CR3 |
內存頁面目錄信息 |
CR4 |
支持處理器特性和說明處理器特性能力的標誌 |
CR3就是所謂的頁目錄地址。
不能直接訪問控制器寄存器中的值,但是可以將數據傳給通用寄存器,然後用通用寄存器的值來賦給控制寄存器.
標誌表
CF |
0 |
進位標誌 |
PF |
2 |
奇偶校驗標誌 |
AF |
4 |
輔助進位標誌 |
ZF |
6 |
零標誌(結果爲0,不是除零的標誌) |
SF |
7 |
符號標誌 |
OF |
11 |
溢出標誌 |
TF |
8 |
陷阱標誌 |
IF |
9 |
中斷使能標誌 |
IOPL |
12和13 |
I/O特權級別標誌 |
NT |
14 |
嵌套任務標誌 |
RF |
16 |
恢復標誌 |
VM |
17 |
虛擬8086模式標誌 |
AC |
18 |
對準檢查標誌 |
VIF |
19 |
虛擬中斷標誌 |
VIP |
20 |
虛擬中斷掛起標誌 |
ID |
21 |
識別標誌 |
1.第一部分狀態標誌(OF之上)
意思基本都很明確
2.第二部分控制標誌
表中沒有顯示,只要是一些指令會自動操作指針,然後自動增減
DF =1,遞減
DF=0遞增
3.第三部分系統標誌
陷阱標誌主要是啓動單步模式.也就是說在運行程序的時候可以一條指令一條指令的執行.也就是同志們熟悉的調試.以前還以爲是通過程序來控制的.現在才發現是在CPU級別上來控制的.
中斷使能標誌.用於描述如何響應外部接受到的信號(估計就是外部中斷).
I/O特權字段標明當前正在運行的任務的I/O特權級別.
嵌套任務標誌控制.當前正在運行的任務是否鏈接到前一個執行的任務.可能是用來恢復中斷的吧(中斷結束後是結束程序,還是繼續程序).
恢復標誌.調試模式中,如何處理響應異常.
至於後面虛擬的幾個標誌我就不說了.win7都已經不支持8086的16位工作模式了.
嗯,彙編的基本介紹已經結束了.