1. 程式人生 > >20189229 張子松 第二周作業

20189229 張子松 第二周作業

inf 當前位置 img 代碼 bubuko 如何 尋址 存儲 試驗

計算機是如何工作的_試驗一

匯編一個簡單的程序

初始程序如下:

int g(int x)
{
  return x + 3;
}

int f(int x)
{
  return g(x);
}

int main(void)
{
  return f(8) + 1;
}

之後,在終端中輸入命令:gcc -S -o main.s main.c -m32
-S目的為輸出匯編文件,-o後跟輸出目標文件名稱,-m32用來產生32位匯編代碼。
打開main.s後為匯編代碼,如圖:
技術分享圖片

匯編文件中有一些“.”打頭的字符串是編譯器在鏈接階段需要的輔助信息或在預編譯階段將頭文件展開的信息,可通過命令:g/.s*/d將其刪掉再進行匯編代碼分析,刪除後如圖:
技術分享圖片

分析匯編指令執行過程

如上圖,簡化後的匯編指令很容易看出只剩g,f,main三個函數,下面對每行匯編指令做簡要分析:

g:
        pushl   %ebp //將ebp的值壓棧,指向4的位置
        movl    %esp, %ebp //ebp也指向esp的位置
        movl    8(%ebp), %eax //變址尋址ebp 加8,賦值給eax
        addl    $3, %eax //將立即數3加到eax中,變為11
        popl    %ebp //將現在ebp的值出棧,指向4的位置,esp指向6
        ret //pop %eip eip指向5的位置
f:
        pushl   %ebp //將ebp的值壓棧,esp向下移動一個存儲單位
        movl    %esp, %ebp //把esp的值賦給ebp(標號)
        subl    $4, %esp //esp減4,指向5的位置
        movl    8(%ebp), %eax //ebp變址尋址8,賦給eax,eax等於8
        movl    %eax, (%esp) //將eax放到esp的位置
        call    g //pushl eip;movl g %eip   此時eip指向g
        leave   //movl %ebp %esp;popl %ebp
        ret  //pop %eip
main:
        pushl   %ebp //把EBP寄存器的值壓棧,先把ESP寄存器指向下一棧空間
        movl    %esp, %ebp //將EBP寄存器變為ESP寄存器的值,指向標號1的位置
        subl    $4, %esp //將ESP向下移動一個棧空間
        movl    $8, (%esp) //將立即數8放入ESP指向的當前位置,標號2
        call    f //pushl eip;movl f %eip   此時eip指向f
        addl    $1, %eax //將立即數1加到eax中
        leave //movl %ebp %esp;popl %ebp
        ret  //pop %eip

如下圖:
技術分享圖片

技術分享圖片

20189229 張子松 第二周作業