韩岩___第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寄存器,后再返回。

 

 

 

 

 

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