20145232韓文浩《信息安全系統設計基礎》第5周學習總結

第三章 程序的機器級表示

尋址方式歷史

Intel處理器系列俗稱x86,開始時它是第一代單芯片。16位爲處理器之一。
8086是第一代,也是彙編課程中學習的處理器型號。html

程序編碼

GCC爲32位執行的默認調用。(gcc -m32)git

  • 在GCC中得到彙編代碼與反彙編
    得到彙編代碼:gcc –S xxx.c –o xxx.s。
    反彙編(將二進制目標文件還原爲彙編代碼)objdump –d xxx.o。
    注:64位機器上想要獲得32位代碼:gcc –m32 –S xxx.c。less

  • 二進制文件能夠用od 命令查看,也能夠用gdb的x命令查看。(WinHex)有些輸出內容過多,咱們可使用 more或less命令結合管道查看,也可使用輸出重定向來查看。
    od code.o | more od code.o > code.txt函數

  • 要查看目標代碼文件的內容,最有價值的是反彙編器
    objdump -d code.ooop

  • 機器代碼和它的反彙編表示的一些特性:
    IA32指令長度從1到15個字節不等
    設計指令格式的方式是,從某個給定位置開始,能夠將字節惟一的解碼成機器指令
    反彙編器只是基於機器代碼文件中的字節序列來肯定彙編代碼,不須要訪問程序的源代碼或彙編代碼
    反彙編器使用的指令命名規則與GCC生成的彙編代碼使用的有些差異學習

數據格式

  • c語言基本數據類型對應的IA32表示
    char 字節 1字節
    short 字 2字節
    int 雙字 4字節
    long int 雙字 4字節
    long long int (不支持) 4字節
    char * 雙字 4字節
    float 單精度 4字節
    double 雙精度 8字節
    long double 擴展精度 10/12字節

訪問信息

  • 數據傳送指令
    MOV類由三條指令組成:
    movb 傳送字節
    movw 傳送字
    movl 傳送雙字
    操做數:
    MOV reg/mem, imm ;當即數寄存器或存儲器 MOV reg/mem/seg, reg ;寄存器的值寄存器/內存/段寄存器 MOV reg/seg, mem ;內存單元的值寄存器/段寄存器 MOV reg/mem, seg ;段寄存器的值寄存器/內存單元 IA32的限制:兩個操做數都不能指向存儲器。測試

  • push&pop
    堆棧:
    1.後進先出
    2.棧指針指向棧頂元素
    3.棧朝低地址方向增加
    壓棧push:
    格式PUSH r16/m16/seg
    功能:
    第一步:SP←SP-2 ;堆棧指針SP上移
    第二步:(SS):(SP)←r16/m16/seg ;字操做數存入堆棧頂部
    出棧pop:
    格式POP r16/m16/seg
    功能:
    第一步:r16/m16/seg← (SS):(SP) ;棧頂的一個字傳送到指定的目的操做數
    第二步:SP←SP+2 ;堆棧指針SP下移,指向新的棧頂ui

算術和邏輯操做

加載有效地址指令

leal,是movl指令的變形,對比彙編中的LEA指令學習。
其實是將有效地址寫入目的操做數。編碼

一元操做和二元操做
  • 一元操做
INC       加1
 DEC       減1
 NEG       取負
 NOT       取補

只有一個操做數,既是源又是目的,能夠是一個寄存器,或者存儲器位置。.net

  • 二元操做
ADD       加
 SUB       減
 IMUL      乘
 XOR       異或
 OR        或
 AND       與

第一個操做數能夠是當即數、寄存器或者存儲器位置
第二個操做數既是源也是又是目的。能夠是寄存器或者存儲器位置,可是不能同時是存儲器位置。
注意操做的順序:第二個操做數 操做符 第一個操做數

  • 移位操做
    先給出移位量,第二項給出要移位的數值。
SAL       左移
 SHL       左移(等同於SAL)
 SAR       算術右移    
 SHR       邏輯右移
  • 特殊操做
    乘法
    乘積截斷
imull   雙操做數
    從兩個32位操做數產生一個32位的乘積。

乘積不截斷

mull    無符號數乘法
    imull   有符號數乘法
     要求一個參數必須在寄存器%eax中,另外一個做爲指令的源操做數給出。
     乘積的高32位在%edx中,低32位在%eax中。

除法
有符號除法

idivl 操做數
     將DX:AX中的64位數做爲被除數,操做數中爲除數
     結果:商在AX中,餘數在DX中。

無符號除法

divl指令
     一般會事先設定寄存器%edx爲0。

控制

條件碼寄存器

CF:進位標誌。最近操做使最高位產生進位。用於檢查無符號操做數的溢出。
ZF:零標誌。最近操做結果爲0。
SF:符號標誌。最近操做獲得的結果爲負數。
OF:溢出標誌。最近操做致使一個補碼溢出。

訪問條件碼

使用方法:根據條件碼的某個組合,將一個字節設置爲0或1。
SET指令:執行比較指令,根據計算t=a-b的結果設置條件碼
能夠條件跳轉到程序的某個其餘部分,能夠有條件的傳送數據。

跳轉指令及其編碼

無條件跳轉
直接跳轉:跳轉目標是做爲指令的一部分編碼的。
間接跳轉:跳轉目標是從寄存器或存儲器位置中讀出的。
當執行與PC相關的尋址時,程序計數器的值是跳轉指令後面的那條指令的地址,而不是跳轉指令自己的地址。

翻譯條件分支

將條件表達式和語句從c語言翻譯成機器語言,最經常使用的方式就是結合有條件和無條件跳轉

if(test-expr)
        then-statement
    else
        else-statement

    (注:test-expr    整數表達式[假/真])
循環

彙編中能夠用條件測試和跳轉組合起來實現循環的效果,可是大多數彙編器中都要先將其餘形式的循環轉換成do-while格式。

  • do-while循環
do
        body-statement
        while(test-expr);

翻譯成以下條件和goto語句:

loop:
        body-statement
        t = test-expr;
        if(t)
            goto loop;
  • while循環
while (test-expr)
    body-statement

轉換成 do-while 形式:

if(!test-expr)
        goto done;
    do
            body-statement
            while(test-expr);
    done:

翻譯成 goto 形式:

t = test-expr;
        if(!t)
            goto done:
    loop:
        body-statement
        t = test-expr;
        if(t)
            goto loop;
    done:
  • for循環
for(init-expr;test-expr;update-expr)
        body-statement

同while形式

init-expr;
    while(test-expr){
        body-statement
        update-expr;
    }

轉換成 do-while 形式:

init-expr;
    if(!test-expr)
        goto done;
    do{
        body-statement
        update-expr;
    }while(test-expr);
    done;

轉換成 goto 代碼:

init-expr
        t = test-expr;
        if(!t)
            goto done:
    loop:
        body-statement
        t = test-expr;
        if(t)
            goto loop;
    done:
Switch語句

Switch語句是多重分支的典型,並且使用的是跳轉表這種數據類型,是的搜索的更快更高效。

因此這裏的關鍵就是要領會使用跳轉表是一種很是有效的實現多重分支的方法。

過程

進入,爲過程的局部變量分配空間
將數據(以過程參數和返回值的形式)和控制從代碼的一部分傳遞到另外一部分。
退出,釋放這些空間。

棧幀: 爲單個過程分配的那部分棧

  • 最頂端的棧幀以兩個指針界定:
寄存器%ebp爲幀指針
 寄存器%esp爲棧指針
  • 棧向低地址方向增加,棧指針%esp指向棧頂元素:
棧指針值適當減少能夠分配沒有指定初始值的數據的空間
 相似的,能夠經過增長棧指針來釋放空間
轉移控制
  • call指令
    目標:指明被調用過程起始的指令地址。
    效果:將返回地址入棧,並跳轉到被調用過程的起始處。

  • ret指令
    從棧中彈出地址,並跳轉到這個位置.
    使用這個指令時,棧指針要指向前面call指令存儲返回地址的位置。

  • leave
    這個指令可使棧作好返回的準備

寄存器使用慣例
  • 程序寄存器組是惟一能被全部過程共享的資源。
  • 必須保證一個過程(調用者)在調用另外一個過程(被調用者)時,被調用者不會覆蓋某個調用者寄存器中的值。

%eax,%edx,%ecx 劃分爲調用者保存寄存器
%ebx,%esi,%edi 劃分爲被調用者保存寄存器
%ebp,%esp 保持寄存器
%eax 保存函數返回值

GDB命令

運行

run(簡寫r): 運行程序,當遇到斷點後,程序會在斷點處中止運行,等待用戶輸入下一步的命令。
continue(簡寫c):繼續執行,到下一個斷點處(或運行結束)
next(簡寫n): 單步跟蹤程序,當遇到函數調用時,直接調用,不進入此函數體;
step(簡寫s):單步調試若是有函數調用,則進入函數;與命令n不一樣,n是不進入調用的函數的
until:運行程序直到退出循環體; / until+行號: 運行至某行
finish: 運行程序,直到當前函數完成返回,並打印函數返回時的堆棧地址和返回值及參數值等信息。
call 函數(參數):調用「函數」,並傳遞「參數」,如:call gdb_test(55)
quit:簡記爲 q ,退出gdb 設置斷點

設置斷點

break n(簡寫b n):在第n行處設置斷點 ;能夠帶上代碼路徑和代碼名稱: bOAGUPDATE.cpp:578)
break func:在函數func()的入口處設置斷點,如:break cb_button
delete 斷點號n:刪除第n個斷點
disable 斷點號n:暫停第n個斷點
enable 斷點號n:開啓第n個斷點
clear 行號n:清除第n行的斷點
info breakpoints(簡寫info b) :顯示當前程序的斷點設置狀況

查看源代碼

list(簡寫l):列出程序的源代碼,默認每次顯示10行。
list 行號:將顯示當前文件以「行號」爲中心的先後10行代碼,如:list 12
list 函數名:將顯示「函數名」所在函數的源代碼,如:list main
list :不帶參數,將接着上一次 list 命令的,輸出下邊的內容。

打印表達式

print 表達式:簡記爲 p ,其中「表達式」能夠是任何當前正在被測試程序的有效表達式,好比當前正在調試C語言的程序,那麼「表達式」能夠是任何C語言的有效表達式,包括數字,變量甚至是函數調用。
print a:將顯示整數 a 的值
print ++a:將把 a 中的值加1,並顯示出來
print name:將顯示字符串 name 的值
print gdb_test(22):將以整數22做爲參數調用 gdb_test() 函數
print gdb_test(a):將以變量 a 做爲參數調用 gdb_test() 函數
display 表達式:在單步運行時將很是有用,使用display命令設置一個表達式後,它將在每次單步進行指令後,緊接着輸出被設置的表達式及值。
watch 表達式:設置一個監視點,一旦被監視的「表達式」的值改變,gdb將強行終止正在被調試的程序。

查詢運行信息

where/bt :當前運行的堆棧列表
set args 參數:指定運行時的參數
show args:查看設置好的參數
info program: 來查看程序的是否在運行,進程號,被暫停的緣由

分割窗口

layout:用於分割窗口,能夠一邊查看代碼,一邊測試
layout src:顯示源代碼窗口
layout asm:顯示反彙編窗口
layout regs:顯示源代碼/反彙編和CPU寄存器窗口
layout split:顯示源代碼和反彙編窗口
Ctrl + L:刷新窗口

實踐過程

C語言編譯器產生的彙編代碼

查看代碼的二進制代碼

將C語言文件編譯成可執行文件並查看可執行文件的二進制內容

將可執行文件反編譯成彙編代碼

將調用函數的棧幀棧底地址入棧,即將bp寄存器的值壓入調用棧中
創建新的棧幀,將被調函數的棧幀棧底地址放入bp寄存器中

本週代碼託管截圖

https://git.oschina.net/albieh

其餘(感悟、思考等,可選)

有很多內容都是在上學期學的彙編基礎上加以鞏固,理解起來比較輕鬆,也遇到了之前許多沒有遇到的命令。

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 16篇 400小時
第一週 80/80 1/1 20/20
第二週 130/210 1/2 18/38
第三週 300/510 1/3 22/60
第五週 300/810 1/4 30/90

參考資料

相關文章
相關標籤/搜索