1. 程式人生 > >2017-2018-1 20155329 《信息安全系統設計基礎》第14周學習總結

2017-2018-1 20155329 《信息安全系統設計基礎》第14周學習總結

即將 由於 過程 call 空間 存在 實現 括號 src

2017-2018-1 20155329 《信息安全系統設計基礎》第14周學習總結

學習目標

找出全書你認為學得最差的一章,深入重新學習一下,要求(期末占5分):

    總結新的收獲

    給你的結對學習搭檔講解或請教,並獲取反饋

第三章程序的機器級表示

數據格式

由於是從16位體系結構擴展成32位,intel用術語字(word)表示16位數據類型,因此32位為雙字(double words),64位數為4字(quad words)。

以下是比較容易模糊的數據類型大小:

       32位機上:float 4    long int 4   double 8    longlong 8    char* 4   unsigned long 4
  64位機上:float 4    long int 8   double 8    longlong 8    char* 8   unsigned long 8

 另外,GCC 用long double表示擴展精度(10字節),出於存儲器性能考慮,會被存儲為12字節

訪問信息

  • 一個IA32 CPU包含一組8個存儲32位值的寄存器,用以存整數數據和指針:eax,ecx,edx,ebx,esi,edi esp,ebp。大多數情況下前六個都用作通用寄存器,eax,ecx,edx的存儲和恢復慣例不同於ebx,edi,esi(前三者為被調用者保存,後三者為調用者保存,詳見3.7.3);最後兩個用於存儲指針,由於在過處理中非常重要,分別指向棧幀的頂部和底部,必須保持。
    技術分享圖片

    操作數指示符

    大多數指令有一到多個操作數,操作數有三種:

       立即數:即常數值
    
       寄存器:表示某個寄存器內容
    
       存儲器引用:根據計算出來的地址(通常稱有效地址)訪問某個存儲器位置

    因此尋址方式也有多種,如:立即數尋址、寄存器尋址、絕對尋址、間接尋址、變址尋址、伸縮化 的變址尋址……

技術分享圖片

數據傳送指令

幾個重要數據傳送指令:mov族(之所以稱這為族是因為mov指令還有很多兄弟指令如movb、movw、movsb、movzb,這是我個人對它們的稱呼,便於記憶mov其他幾個比較低調的兄弟)、pop、push。



 另,對於mov族,movb、movw自不必做過多解釋,movsb、movzb分別為符號擴展、零擴展,它們只拷貝一個字節,源操作數均為單字節,並設置目的操作數中其余的位,效果如下:

  初始假設:%dh=8D  %eax=98765432

  1   movb   %dh,%al       ;%eax=9876548D

  2   movsbl %dh,%eax    ;%eax=FFFFFF8D(目的操作數高24位設為源字節最高位,在這裏為很顯然為1,所以前24位為全F)

  3   movzbl %dh,%eax    ;%eax=0000008D(目的操作數高24位被設為0)



 對於pushl指令等價於:

      subl $4,%esp

      movl %ebp,(%esp)  //註意這裏的括號引起的差別



  popl指令等價於:

       movl (%esp),%eax

       addl $4,%esp

技術分享圖片

    /*******C代碼**********/         
    int exchange(int *xp, int y){                                 
        int x =  *xp;  
        *xp = y;  
        return x;  
    }  
      
    //*********匯編代碼******/  
    //1 movl 8(%ebp),%eax   Get xp  
    //2 movl 12(%ebp),%edx  Get y  
    //3 movl (%eax),%ecx    Get x at *xp  
    //4 movl %edx,(%eax)    Store y at *xp  
    //5 movl %ecx,%eax      Set x as return value   
收獲
  1. 指針其實是地址,間接引用指針就是將該指針放在一個寄存器中,然後在間接存儲器引用中引用這個寄存器
  2. 局部變量通常保存在寄存器中,而不是存儲器

    過程

  • 一個過程調用包括將數據(以過程參數和返回值的形式)和控制從代碼的一部分傳遞到另一部分。另外,它還必須在進入時為過程的局部變量分配空間,並在退出時釋放這些空間。
棧幀結構
  • 棧幀結構指的是為單個過程分配的那部分棧。棧幀的最頂端是以兩個指針定界的,寄存器%ebp作為幀指針,寄存器%esp作為棧指針。棧指針是可以移動的,所以大多數信息的訪問都是相對於幀指針的 。
轉移控制

call :過程調用

leave:為返回準備棧

ret:從過程調用中返回

遞歸過程

技術分享圖片

錯題總結

技術分享圖片
技術分享圖片
技術分享圖片

家庭作業

3.59
  • 這個題考察的是2.3.4和2.3.5節的一個定理:w比特長度的兩個數相乘,會產生一個2w長度的數,不管這兩個數是無符號數還是補碼表示的有符號數,把結果截取的低w比特都是相同的。

所以我們可以用無符號數乘法指令mulq實現有符號數乘法:先把數有符號擴展致2w位,然後把這兩個2w位的數相乘,截取低2w位即可。

截取就是求模運算,即 mod 2^w。

store_prod
    movq    %rdx, %rax      #rax中保存y
    cqto                    #將rax有符號擴展為rdx:rax,即rdx為全1
    movq    %rsi, %rcx      #rcx中保存x
    sarq    $63, %rcx       #rcx為為全1若x小於0,否則為0,即將x有符號擴展
    #下面把這兩個擴展的數當成無符號數進行運算,取低128bit。
    #此時y表示為rdx:rax,x表示為rcx:rsi, 即y = rdx*2^64 + rax, x = rcx*2^64 + rsi
    #x*y = rdx*rcx*2^128 + rdx*rsi*2^64 + rcx*rax*2^64 + rax*rsi
    #由於我們只需要取低128位,所以對x*y進行取模操作mod 128,得到公式:rdx*rsi*2^64mod2^128 + rcx*rax*2^64mod2^128 + rax*rsi
    #由於這裏的寄存器都是64位的,所以對於rdx*rsi*2^64mod2^128這樣的操作我們可以直接使用imulq指令,截取兩個寄存器相乘的低64位,然後把他加到rax*rsi的高64位。
    #下面實現公式
    imulq   %rax, %rcx      #rcx*rax*2^64mod2^128(隨後放在高64位)
    imulq   %rsi, %rdx      #rdx*rsi*2^64mod2^128(隨後放在高64位)
    addq    %rdx, %rcx      #隨後放在高64位
    mulq    %rsi            #x*y即rax*rsi
    addq    %rcx, %rdx      #放在高64位
    movq    %rax, (%rdi)    #存儲低64位
    movq    %rdx, 8(%rdi)   #存儲高64位
    ret

2017-2018-1 20155329 《信息安全系統設計基礎》第14周學習總結