(3)Hello World反組譯碼分析

來源:互聯網
上載者:User

實驗環境:visual c++ 6.0

實驗目的:通過組合語言分析一個簡單的c程式在程式執行時的記憶體配置情況

/*******mymain.cpp*********/

1:    #include<stdio.h>

2:     int main()

3:     {

4:         int x=1;

5:        printf("Hello Canney\n");

6:         return0;

7:     }

 

 

/*******mymain.asm*********/

1:    #include<stdio.h>

2:     int main()

3:     {

00410950  push        ebp

00410951  mov         ebp,esp

00410953  sub         esp,44h     // esp=esp-0x40,分配棧空間給局部變數。移動單位為位元組

00410956  push        ebx

00410957  push        esi

00410958  push        edi

00410959   lea        edi,[ebp-44h]

0041095C   mov        ecx,11h

00410961   mov        eax,0CCCCCCCCh

00410966   rep stos   dword ptr [edi]

4:         int x=1;

00410968  mov         dword ptr [ebp-4],1

5:        printf("Hello Canney\n");

0041096F  push        offset string"Hello Canney\n" (0042601c)    //字串常量,存放在0x0042201c(.rodata地區)

00410974  call        printf (00401080)                          //調用printf函數,函數入口在0x00401060

00410979  add         esp,4

6:         return0;

0041097C  xor         eax,eax                                 //eax=0,清空eax

7:     }

0041097E  pop         edi

0041097F  pop         esi

00410980  pop         ebx

00410981  add         esp,44h                   

00410984  cmp         ebp,esp

00410986   call        __chkesp (004011b0)                       //檢查棧是否被破壞

0041098B  mov         esp,ebp

0041098D  pop         ebp

0041098E   ret          //棧頂字單元出棧,其值賦給IP寄存器。即實現了一個程式的轉移,將棧頂字單元儲存的位移地址

 

補充知識:

1.32位機器8個通用寄存器

①資料寄存器

資料寄存器主要用來儲存運算元和運算結果等資訊,從而節省讀取運算元所需佔用匯流排和訪問儲存空間的時間。32位CPU有4個32位的通用寄存器EAX、EBX、ECX和EDX。對低16位元據的存取,不會影響高16位的資料。這些低16位寄存器分別命名為:AX、BX、CX和DX,它和先前的CPU中的寄存器相一致。

4個16位寄存器又可分割成8個獨立的8位寄存器(AX:AH-AL、BX:BH-BL、CX:CH-CL、DX:DH-DL),每個寄存器都有自己的名稱,可獨立存取。程式員可利用資料寄存器的這種“可分可合”的特性,靈活地處理字/位元組的資訊。寄存器AX和AL通常稱為累加器(Accumulator),用累加器進行的操作可能需要更少時間。累加器可用於乘、除、輸入/輸出等操作,它們的使用頻率很高;寄存器BX稱為基地址寄存器(BaseRegister)。它可作為儲存空間指標來使用;寄存器CX稱為計數寄存器(CountRegister)。在迴圈和字串操作時,要用它來控制迴圈次數;在位操作中,當移多位時,要用CL來指明移位的位元;

寄存器DX稱為資料寄存器(DataRegister)。在進行乘、除運算時,它可作為預設的運算元參與運算,也可用於存放I/O的連接埠地址。在16位CPU中,AX、BX、CX和DX不能作為基址和變址寄存器來存放儲存單元的地址,但在32位CPU中,其32位寄存器EAX、EBX、ECX和EDX不僅可傳送資料、暫存資料儲存算術邏輯運算結果,而且也可作為指標寄存器,所以,這些32位寄存器更具有通用性。

 

②變址寄存器

32位CPU有2個32位通用寄存器ESI和EDI。其低16位對應先前CPU中的SI和DI,對低16位元據的存取,不影響高16位的資料。寄存器ESI、EDI、SI和DI稱為變址寄存器(IndexRegister),它們主要用於存放儲存單元在段內的位移量,用它們可實現多種儲存空間運算元的定址方式,為以不同的地址形式訪問儲存單元提供方便。變址寄存器不可分割成8位寄存器。作為通用寄存器,也可儲存算術邏輯運算的運算元和運算結果。它們可作一般的儲存空間指標使用。在字串操作指令的執行過程中,對它們有特定的要求,而且還具有特殊的功能。

 

③指標寄存器

32位CPU有2個32位通用寄存器EBP和ESP。其低16位對應先前CPU中的SBP和SP,對低16位元據的存取,不影響高16位的資料。寄存器EBP、ESP、BP和SP稱為指標寄存器(PointerRegister),主要用於存放堆棧記憶體儲單元的位移量,用它們可實現多種儲存空間運算元的定址方式,為以不同的地址形式訪問儲存單元提供方便。指標寄存器不可分割成8位寄存器。作為通用寄存器,也可儲存算術邏輯運算的運算元和運算結果。它們主要用於訪問堆棧內的儲存單元,並且規定:

(1)BP為基指標(BasePointer)寄存器,用它可直接存取堆棧中的資料;

(2)SP為堆棧指標(StackPointer)寄存器,用它只可訪問棧頂。

 2.repstos指令

rep指令的目的是重複其後的指令.ECX的值是重複的次數. rep可以是任何字串指令(CMPS, LODS, MOVS,SCAS, STOS)的首碼. rep能夠引發其後的字串指令被重複, 只要ecx的值不為0, 重複就會繼續. 每一次字串指令執行後, ecx的值都會減小.

stos指令的作用是將eax中的值拷貝到edi指向的地址.如果設定了direction flag, 那麼edi會在該指令執行後減小, 如果沒有設定direction flag, 那麼edi的值會增加.

stos((store into String),意思是把eax的內容拷貝到目的地址。用法:stos dst,dst是一個目的地址,例如:stos dword ptres:[edi]。dword ptr首碼告訴stos,一次拷貝雙字(32個位元組)的資料到目的地址。為什麼一次非要拷貝雙字呢?這和eax寄存器有關,到底神馬關係,慢慢道來…

    執行stos之前必須往eax(32為寄存器)放入要拷貝的資料。中,eax的內容是cccccccc,不用說都明白int3中斷。這段代碼是初始化堆棧和分配局部變數用的,往分配好的局部變數空間放入int3中斷的原因是:防止該空間裡的東東被意外執行。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.