zoukankan      html  css  js  c++  java
  • 用汇编来解释“计算机是怎么工作的”

    本文章为《Linux内核分析》实验报告

    梁永锐

    原创作品转载请注明出处 http://www.cnblogs.com/liangyongrui/p/6392035.html 

    《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”

    -----

    以下为要分析的c代码

    int g(int x)
    {
        return x + 36;
    }
    
    int f(int x)
    {
        return g(x) * 4;
    }
    
    int main(void)
    {
        return f(81) + 12;
    }
    gcc –S –o main.s main.c -m32

    编译成32位汇编后(去了点开头的行

    g:
        pushl    %ebp
        movl    %esp, %ebp
        movl    8(%ebp), %eax
        addl    $36, %eax
        popl    %ebp
        ret
    f:
        pushl    %ebp
        movl    %esp, %ebp
        pushl    8(%ebp)
        call    g
        addl    $4, %esp
        sall    $2, %eax
        leave
        ret
    main:
        pushl    %ebp
        movl    %esp, %ebp
        pushl    $81
        call    f
        addl    $4, %esp
        addl    $12, %eax
        leave
        ret

    一.实验截图:

    二. 汇编代码的工作过程中堆栈的变化

    从main开始

    pushl %ebp
    
    movl %esp, %ebp

    也就是enter指令(不知道为什么这里并没有把他写成enter而是分开写了)

    这两条指令执行后我们假设,ebp,esp均为100(以下内容用ebp=100,  esp=100这种方法表示)

    pushl $81

    ebp=100, esp = 96,[96]=81([96]=81, 表示位置96的地方存了81这个数, 以下均用这种方法表示)

    call f

    ebp = 100, esp = 92, [92]= 22(这里用行号做eip)

    跳到了f

    pushl %ebp

    ebp = 100, esp = 88, [88]=100

    movl    %esp, %ebp

    ebp = 88, esp = 88

    pushl 8(%ebp)

    ebp = 88, esp = 84, [84] = 81

    call    g

    ebp = 88, esp = 80, [80] = 13

    然后调到了g函数

    pushl    %ebp

    ebp = 88, esp = 76, [76] = 88

    movl    %esp, %ebp

    ebp = 76, esp = 76

    movl    8(%ebp), %eax

    把传入的参数放在eax中, eax = 81

    addl    $36, %eax

    eax = 81 + 36 = 117

    popl    %ebp

    ebp = 88, esp = 80

    ret

    ebp = 88, esp = 84, eip = 13

    此时就跳到13行了

    addl    $4, %esp

    弹出传入的参数,不赋值

    ebp = 88, esp = 88

    sall    $2, %eax

    编译器很智能,乘4,自动变成了左移两位, eax = 117 << 2 = 468

    leave

    leave就是

    movl %ebp, %esp  : ebp = 88, esp = 88

    popl %ebp : ebp = 100, esp = 92

    ret

    ebp = 100, esp = 94, eip = 22

    跳到第22行

    addl    $4, %esp

    弹出参数 

    esp = 96

    addl $12, %eax

    eax = 468 + 12 = 480

    leave
    ret

    回到main函数之前的堆栈和eip

    三.计算机是如何工作的

    简单的说,计算机就是按照ip一条条的执行指令,执行的时候需要一些寄存器做辅助,ip有时候也会跳。

  • 相关阅读:
    paip.解决Invalid byte 2 of 2byte UTF8 sequence.
    poj1157
    poj1258
    poj1160
    poj1113
    poj1159
    !!!GRETA正则表达式模板类库
    【原创】C#与C++的混合编程采用其中的第三种方法
    WinApi.cs
    C#:正则表达式30分钟入门教程
  • 原文地址:https://www.cnblogs.com/liangyongrui/p/6392035.html
Copyright © 2011-2022 走看看