zoukankan      html  css  js  c++  java
  • 通过反汇编代码探究计算机运行过程

    在线学习了Mooc的《计算机内核分析》课程,为了探究计算机运行过程,现做博文记录实验过程。


    首先打开虚拟机中的linux环境,输入C语言代码:

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


    保存为main.c文件


    使用反汇编命令

    gcc -S -o main.s main,c -m32

    -S : 编译为汇编语言程序

    -o : 指定目标程序名称

    -m32 : 指定编译为32位环境的汇编代码


    编译结果:

    	.file	"main.c"
    	.text
    	.globl	g
    	.type	g, @function
    g:
    .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_def_cfa 4, 4
    	.cfi_restore 5
    	ret
    	.cfi_endproc
    .LFE0:
    	.size	g, .-g
    	.globl	f
    	.type	f, @function
    f:
    .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, @function
    main:
    .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)
    	call	f
    	addl	$1, %eax
    	leave
    	.cfi_restore 5
    	.cfi_def_cfa 4, 4
    	ret
    	.cfi_endproc
    .LFE2:
    	.size	main, .-main
    	.ident	"GCC: (GNU) 4.6.2 20111027 (Red Hat 4.6.2-1)"
    	.section	.note.GNU-stack,"",@progbits

    除去代码中的标志符号后:

    g:
    	pushl	%ebp
    	movl	%esp, %ebp
    	movl	8(%ebp), %eax
    	addl	$3, %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	$8, (%esp)
    	call	f
    	addl	$1, %eax
    	leave
    	ret

    下面对此段汇编代码进行分析,首先要熟悉一些基本的汇编知识:

    为了计算方便,加快计算机运行速度,计算机中配置了很多寄存器,这些寄存器在计算机工作中起到各种不同的重要作用:

    eax默认作为函数返回值保存寄存器

    ebp为栈低指针寄存器

    esp为栈顶指针寄存器(运行中的每个程序都有一段堆栈空间,用来存放程序运行时数据)

    eip为当前指令位置寄存器

    push为压栈指令

    pop为出栈指令

    mov为转移指令,通过该指令有七种寻址方式:
    mov eax,0x1234 //立即寻址
    mov eax,ebx //寄存器寻址
    mov eax,[ebx] //寄存器间接寻址
    mov eax,[0x1234] //直接寻址
    mov eax,[ebx+0x1234] //寄存器相对寻址
    mov eax,[esi+edi] //基址变址寻址
    mov eax,[esi+edi+0x1234] //基址变址相对寻址

    add为加法指令

    此外还有一些宏指令,它们对应一行或多行汇编代码:

    ret : pop %eip(实则返回指令)

    leave : mov %ebp %esp

    pop %ebp

    enter :  push %ebp

    mov %esp %ebp

    call 0x12345 : push %eip

    mov $0x12345 , %eip

    在指令后加上b、l、w、q分别代表8位、16位、32位、64位操作


    下面直接通过分析代码来熟悉这些指令:

    首先程序从main函数开始执行,

    pushl	%ebp

    将基址寄存器的值进栈,用于系统控制main函数返回,此时堆栈情况如图:


    movl	%esp, %ebp

    此行代码将esp寄存器的内容赋值给ebp,即ebp和esp都指向地址1的位置

    subl	$4, %esp

    将esp的指针指向下面一个位置

    movl	$8, (%esp)

    将立即数8存放在当前esp所指位置,堆栈的情况如图:


    call	f

    调用f函数,即执行下面的指令

    push %eip //将当前的eip入栈,即将下一条指令[addl $1, %eax]的地址入栈

    mov f, %eip //函数f的入口地址赋值到eip中,即程序跳转到f函数入口处

    pushl	%ebp

    f函数的第一条指令,同main函数,如图:


    movl	%esp, %ebp

    初始化f函数的堆栈,如图:


    subl	$4, %esp<span style="white-space:pre">		</span>//栈顶下移

    movl	8(%ebp), %eax<span style="white-space:pre">		</span>//栈低加8对应地址的数据存入eax中
    movl	%eax, (%esp)<span style="white-space:pre">			</span>//eax中数据存入esp所指空间
    如图:


    call	g

    调用g函数

    pushl	%ebp
    movl	%esp, %ebp
    movl	8(%ebp), %eax
    addl	$3, %eax

    如图:


    popl	%ebp

    出栈,如图:


    ret<span style="white-space:pre">		</span>//pop %eip

    eip指向f函数中leave指令的地址,开始继续执行


    leave

    mov %ebp %esp

    pop %ebp


  • 相关阅读:
    poj 2584 T-Shirt Gumbo (二分匹配)
    hdu 1757 A Simple Math Problem (乘法矩阵)
    矩阵之矩阵乘法(转载)
    poj 2239 Selecting Courses (二分匹配)
    hdu 3661 Assignments (贪心)
    hdu 1348 Wall (凸包)
    poj 2060 Taxi Cab Scheme (二分匹配)
    hdu 2202 最大三角形 (凸包)
    hdu 1577 WisKey的眼神 (数学几何)
    poj 1719 Shooting Contest (二分匹配)
  • 原文地址:https://www.cnblogs.com/slz-coder150315/p/4376366.html
Copyright © 2011-2022 走看看