2017-2018-1 20155207 《信息安全系統設計基礎》第5周學習總結
教材學習內容總結
這章爲咱們講述瞭如何有C編譯器生成的x86-84機器代碼,還講述了過程的實現,包括棧分配、寄存器使用慣例和參數傳遞。html
第三章 程序的機器級表示
- 計算機執行機器代碼,用字節序列編碼低級的操做
- GCC C以彙編代碼的形式產生輸出,彙編代碼是機器代碼的文本表示
- 3.1 歷史觀點
- 平坦尋址模式:程序員將整個存儲空間看做一個大的字節數組,Linux和DOS使用
- 分段模式:8086
- IA32:帶保護模式的平坦尋址方式
- 3.2 程序編碼
- 編譯P1.c和P2.c:gcc -01 -o -m32 p p1.c p2.c
-01
第一級優化,編譯時間長,程序性能方面考慮,第二級優化是較好的選擇
- C預處理器擴展源代碼,彙編器產生源代碼的彙編代碼後綴
.s
,彙編器再將彙編代碼轉換成二進制目標代碼後綴.o
, 連接器將目標代碼文件與實現庫函數的代碼合併,產生最中國的可執行代碼文件p
- 3.2.1 機器級代碼
- 指令集體系結構(ISA):機器級程序的格式和行爲,定義了處理器狀態、指令的格式以及每條指令對狀態的影響
- 虛擬地址:使用的存儲器地址
- 程序計數器(PC):指示下一條指令在存儲器中的地址
- 寄存器文件:8個命名的位置,分別存儲32位的值,能夠存儲地址或整數數據
- 條件碼寄存器:實現控制或數據流中的條件變化
- 浮點寄存器
- 3.2.2 代碼示例
- 命令行中使用
-s
獲得彙編代碼,使用-c
會編譯並彙編
- 反彙編器:帶
-d
命令行標誌的程序OBJDUMP
- 3.2.3 關於格式的註解
- 3.3 數據格式
- 字表示16位數據類型
- int、long int、全部指針都用雙字,浮點數單精度4字節、雙精度8字節、擴展精度10字節
- 3.4 訪問信息
- 3.4.1 操做數指示符
- 操做數三種類型:當即數(
$-577
)、寄存器(Ea
表示寄存器R[Ea]
表示寄存器值)、存儲器(Mb[Addr]
表示對存儲在存儲器中從地址Addr開始的b個字節值的引用)
- 3.4.2 數據傳送指令
- MOV傳送,MOVS符號拓展,MOVZ零拓展
- 將一個值從一個存儲器位置複製到另外一個存儲器位置須要兩條指令
- 3.4.3 數據傳送實例
- 3.5 算數和邏輯操做
- 3.5.1 加載有效地址
leal
將源操做數存儲器的地址寫入到目的操做數寄存器中
- 3.5.2 一元操做和二元操做
- 一元操做操做數能夠是寄存器或存儲器位置
- 二元操做第一個操做數能夠是當即數、寄存器或存儲器位置,第二個操做數能夠是寄存器或存儲器位置,兩操做數不能同時爲存儲器位置
- 3.5.3 移位操做
- SAL、SRL都是左移指令,SAR算數右移、SLR邏輯右移
- 3.5.4 討論
- 編譯器產生的代碼中,會用一個寄存器存放多個程序值,還會在寄存器之間傳送程序值
- 3.5.5 特殊的算數操做
- 無符號乘法(mull)補碼乘法(imull):一個參數必須存放在%eax,而另外一個做爲指令的源了操做數給出,乘積存放在%edx和%eax中
- 除法將%edx和%eax中的64位數做爲被除數,商存儲在%eax中,餘數存儲在%edx
- 3.6 控制
- 3.6.1 條件碼
- CF進位標誌,檢查無符號數的溢出
- ZF零標誌
- SF符號標誌
- OF溢出標誌
- 除了只設置條件碼而不更新目標寄存器外,CMP與SUB行爲相同,TEST與ADD行爲相同
- 3.6.2 訪問條件碼
- 條件碼使用方法:1)根據條件碼的組合,設置字節爲0或1 2)條件跳轉到程序其餘部分 3)條件傳送數據
- SET指令的目的操做數是8個單字節寄存器元素之一或是存儲一個字節的存儲器位置
- 3.6.3 跳轉指令及其編碼
- 直接跳轉:跳轉目標是做爲指令的一部分編碼的
- 間接跳轉:跳轉目標是從寄存器或存儲器位置中讀出的
- 執行與PC相關尋址時,程序計數器的值是跳轉指令後面的那條指令的地址
- 3.6.4 翻譯條件分支
- 3.6.5 循環
- do-while循環:至少執行一次
- while循環:第一次執行以前,循環可能停止,使用條件分支,在須要時省略循環體的第一次執行
- for循環:先給出初始化條件
- 3.6.6 條件傳送指令
- 基於條件數據傳送的代碼比基於條件控制轉移的代碼性能好
- 3.6.7 switch語句
- 使用跳轉表
- 跳轉表對重複狀況的處理是使用相同的代碼標號,對缺失狀況的處理使用默認標號
- 3.7 過程
- 數據傳遞、局部變量的分配和釋放經過操縱程序棧來實現
- 3.7.1 棧幀結構
- IA32用程序棧支持過程調用
- 機器用棧來傳遞過程參數、存儲返回信息、保存寄存器用於之後恢復
- 棧幀:爲單個過程分配的棧
- %ebp爲幀指針、%esp爲棧指針,棧指針能夠移動,大多數信息訪問相對於幀指針
- 3.7.2 轉移控制
- call指令的效果:返回地址入棧,並跳轉到被調用過程的起始處,返回地址是在程序中緊跟在call後面那條指令的地址
- ret指令從棧中彈出地址
- 3.7.3 寄存器使用慣例
- 程序寄存器組是惟一能被全部過程共享的資源
- %eax、%edx、%ecx被劃分爲調用者保存寄存器
- %ebx、%esi、%edi被劃分爲被調用者保存寄存器
- 3.7.4 過程示例
- 「創建」初始化棧、「主體」執行過程實際計算、「結束」恢復棧初始狀態以及過程返回
- 3.7.5 遞歸過程
教材學習中的問題和解決過程
- 練習3.33 D
- 作此題的時候,很不理解%esp和偏移量爲+四、+8兩個位置存儲的數值是如何造成的,後來反覆研究GCC生成的彙編代碼,發現是將字符串「%x %x」存儲在%esp的位置,同時經過leal命令,將x和y的位置存儲在+八、+4的位置
代碼調試中的問題和解決過程
(statistics.sh腳本的運行結果截圖)java
上週考試錯題總結
- 把add.c sub.c mul.c div.c編譯成一個共享庫libmath.so的命令是:gcc -shared -fpic -o libmath.so add.c sub.c mul.c div.c
- Linux中,目標文件XXX.o中的代碼和數據節是從地址0開始的
結對及互評
點評模板:
- 博客中值得學習的或問題:
- 代碼中值得學習的或問題:
- 其餘
本週結對學習狀況
- [20155223](http://www.cnblogs.com/battlefieldheros/p/7705963.html)
- 結對照片
- 結對學習內容
- XXXX
- XXXX
- ...
其餘(感悟、思考等,可選)
這周學習了將C語言代碼轉化爲彙編代碼,上學習有學過彙編這門課,因此前面一些代碼仍是有些熟悉的,對於後面不大熟悉的彙編代碼,能夠經過學習這張來溫習git
學習進度條
目標 |
5000行 |
30篇 |
400小時 |
|
第一週 |
200/200 |
2/2 |
20/20 |
|
第二週 |
300/500 |
2/4 |
18/38 |
|
第三週 |
500/1000 |
3/7 |
22/60 |
|
第四周 |
300/1300 |
2/9 |
30/90 |
|
嘗試一下記錄「計劃學習時間」和「實際學習時間」,到期末看看能不能改進本身的計劃能力。這個工做學習中很重要,也頗有用。
耗時估計的公式
:Y=X+X/N ,Y=X-X/N,訓練次數多了,X、Y就接近了。程序員
參考:軟件工程軟件的估計爲何這麼難,軟件工程 估計方法數組
計劃學習時間:8小時安全
實際學習時間:8小時函數
改進狀況:性能
(有空多看看現代軟件工程 課件
軟件工程師能力自我評價表)學習
參考資料