韓巖___第1課___《linux內核分析》MOOC課


題目:C語言生成彙編代碼的執行流程

1、  C語言代碼如下:

int g(int x)

{

      return x + 10;

}

 

int f(int x)

{

      return g(x);

}

 

int main(void)

{

      return f(1) + 1;

}


2、  使用命令:gcc –S –o main.s main.c -m32(說明:生成是32位的彙編指令,系統是32位linux系統CentOS5.5,其他不同位系統生成代碼略有不同) 生成彙編代碼後如下:

以“.”開頭的代碼是註釋代碼

     .file "main.c"

     .text

     .globl      g

     .type       g, @function

g:

.LFB0:

     .cfi_startproc

     pushl       %ebp

     .cfi_def_cfa_offset8

     .cfi_offset5, -8

     movl       %esp, %ebp

     .cfi_def_cfa_register5

     movl       8(%ebp), %eax

     addl $10, %eax

     popl %ebp

     .cfi_restore5

     .cfi_def_cfa4, 4

     ret

     .cfi_endproc

.LFE0:

     .size g, .-g

     .globl      f

     .type       f, @function

f:

.LFB1:

     .cfi_startproc

     pushl       %ebp

     .cfi_def_cfa_offset8

     .cfi_offset5, -8

     movl       %esp, %ebp

     .cfi_def_cfa_register5

     subl $4, %esp

     movl       8(%ebp), %eax

     movl       %eax, (%esp)

     call  g

     leave

     .cfi_restore5

     .cfi_def_cfa4, 4

     ret

     .cfi_endproc

.LFE1:

     .size f, .-f

     .globl      main

     .type       main, @function

main:

.LFB2:

  .cfi_startproc

  pushl       %ebp

  .cfi_def_cfa_offset8

  .cfi_offset5, -8

  movl       %esp, %ebp

  .cfi_def_cfa_register5

  subl $4, %esp

  movl       $1, (%esp)

  call  f

  addl $1, %eax

  leave

  .cfi_restore5

  .cfi_def_cfa4, 4

  ret

  .cfi_endproc

.LFE2:

     .size main, .-main

     .ident      "GCC: (Ubuntu 4.8.2-19ubuntu1)4.8.2"

     .section   .note.GNU-stack,"",@progbits


3、  執行流程

簡化後代碼:

 g:

       pushl       %ebp

     movl       %esp, %ebp

     movl       8(%ebp), %eax

     addl $10, %eax

     popl %ebp

     ret

f:

  pushl       %ebp

  movl       %esp, %ebp

  subl $4, %esp

  movl       8(%ebp), %eax

  movl       %eax, (%esp)

  call  g

  leave

  ret

main:

  pushl       %ebp

  movl       %esp, %ebp

  subl $4, %esp

  movl       $1, (%esp)

  call  f

  addl $1, %eax

  leave

  ret

執行過程:

首先從main函數開始執行,將ebp寄存器地址入棧並將esp指針指向ebp,esp地址減去4個字節,變成紅色指向的內容,然後將1賦值給esp指針。

然後是系統保存當前的環境變量,調用f函數。此工作過程與main函數調用是一樣的,不同是將8賦值了給eax寄存器,再eax寄存器的值賦值給esp指針。

然後是系統保存當前的環境變量,調用g函數。此工作過程與f函數調用是一樣的,將數值10與eax寄存器的值相加,ebp寄存器出棧,返回f調用函數處的下一條指令。同樣的,ebp寄存器出棧,返回main調用函數處的下一條指令,eax寄存器加1後並將值賦值eax寄存器,後再返回。

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章