Linux内核分析-1/反汇编(堆栈)

来源:互联网 发布:结婚录像制作软件 编辑:程序博客网 时间:2024/05/29 09:44

《Linux内核分析》MOOC课程


运行环境:实验楼


/*main.c*/int g(int x){  return x + 3;}int f(int x){  return g(x);}int main(void){  return f(8) + 1;}

/*Makefile*/all:    gcc –S –o main.s main.c -m32

/*main.s*/    .file   "main.c"    .text    .globl  g    .type   g, @functiong:.LFB0:    .cfi_startproc    pushl   %ebp    .cfi_def_cfa_offset 8    .cfi_offset 5, -8    movl    %esp, %ebp    .cfi_def_cfa_register 5    movl    8(%ebp), %eax    addl    $3, %eax    popl    %ebp    .cfi_restore 5    .cfi_def_cfa 4, 4    ret    .cfi_endproc.LFE0:    .size   g, .-g    .globl  f    .type   f, @functionf:.LFB1:    .cfi_startproc    pushl   %ebp    .cfi_def_cfa_offset 8    .cfi_offset 5, -8    movl    %esp, %ebp    .cfi_def_cfa_register 5    subl    $4, %esp    movl    8(%ebp), %eax    movl    %eax, (%esp)    call    g    leave    .cfi_restore 5    .cfi_def_cfa 4, 4    ret    .cfi_endproc.LFE1:    .size   f, .-f    .globl  main    .type   main, @functionmain:.LFB2:    .cfi_startproc    pushl   %ebp                //将栈底压栈    .cfi_def_cfa_offset 8    .cfi_offset 5, -8    movl    %esp, %ebp          //将栈顶的值赋给栈底    .cfi_def_cfa_register 5    subl    $4, %esp           //栈顶    movl    $8, (%esp)         //将8赋给栈顶    call    f    addl    $1, %eax    leave    .cfi_restore 5    .cfi_def_cfa 4, 4    ret    .cfi_endproc.LFE2:    .size   main, .-main    .ident  "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"    .section    .note.GNU-stack,"",@progbits

gcc  –o main main.c -m32 //可以编译为可执行文件//然后在命令行下./main 就开始执行了//这个过程大概是bash解析了命令行.并fork并exec了main将main从设备块中读取到高速缓冲块中,然后拷贝到用户空间的对应段上.?,并建立栈顶esp和栈底ebp和eip//栈顶在栈底下面,中间无间隔,eip指向main中的 pushl %ebp然后从main开始运行,在栈内?//栈内的哪个地址?假设栈内的地址为0xbfe5 d38f,栈向下增长
/*用户栈*//*从高到*/主程序的参数主程序调用后的返回地址第0帧地址局部变量fun1的参数fun1调用后的返回地址第1帧地址局部变量

汇编代码解析



main



  • main标号内的pushl执行之前的状态

这里写图片描述

  • pushl %ebp
下面的图表示是上面的语句执行完之后的状态即下图表示的是 pushl    %ebp 后的状态

这里写图片描述

  • movl %esp, %ebp

这里写图片描述

  • subl $4, %esp

这里写图片描述

  • movl $8, (%esp)

这里写图片描述

  • call f

这里写图片描述


f


  • pushl %ebp

这里写图片描述

  • movl %esp, %ebp

这里写图片描述

  • subl $4, %esp

这里写图片描述

  • movl 8(%ebp), %eax
该行没有改变栈,只是将(ebp-8)地址内的值(8)付给了eax
  • movl %eax, (%esp)

这里写图片描述

  • call g

这里写图片描述


g


  • pushl %ebp

这里写图片描述

  • movl %esp, %ebp

这里写图片描述

  • movl 8(%ebp), %eax
该行没有改变栈,只是将(ebp-8)地址内的值(8)付给了eax
  • addl $3, %eax
改行没有改变栈,只是将eax加了3,此时为11
  • popl %ebp

这里写图片描述

  • g:ret

这里写图片描述


f


  • f : leave

这里写图片描述

  • f:ret

这里写图片描述


main


  • addl $3, %eax
此时没改变堆栈,只是将eax中的值加了3,此时为14
  • leave

这里写图片描述

  • ret

这里写图片描述


注意:

这里面需要注意的是%eax是独立于栈存在的,所以不会消失,所以返回值都存在%eax寄存器中栈分为四种,这里面分析的栈是满减栈,另外还有空减栈,满增栈,满减栈

参考资料


Push, Pop, call, leave 和 Ret 指令图解

阅读全文
0 0