zoukankan      html  css  js  c++  java
  • 20135202闫佳歆--week1 计算机是如何工作的

    计算机是如何工作的

    这一周我学习了计算机工作的相关知识。

    最基础的,就是冯诺依曼体系结构结构,它最核心的思想是存储程序计算机,要点是:数字计算机的数制采用二进制;计算机应该按照程序顺序执行。

    除了思想之外,我还复习了曾经学过的汇编相关的知识,包括操作数的类型,寻址的几种方式,还有一些具体的操作指令。这些指令我是第三次接触了,在我之前做过的一篇学习总结中已经有过详细的论述,这里就不再赘述,列出地址给予参考。

    =link

    在过往的学习中我了解到,汇编语言是一种机器语言,通过对堆栈,对存储器,对寄存器,等等的操作,来实现一系列的指令。我们日常所使用的诸如c语言这种高级语言,落到具体操作的时候,在计算机的层面,还是依靠汇编语言来执行的,高级语言中简单的一行代码,汇编语言就可能需要很多很多行来逐一实现。这种实现是顺序进行的,通过一些转移指令进行跳转,跳转时又依赖堆栈来保持数据和栈指针。

    这种机理,作业中的实验可以很直接的表现出来。

    具体实验的步骤,在上学期的课程中已经实践过了,参见上述地址对应总结中最后的作业部分,有实验所用代码,执行语句,精简后的反汇编代码,以及简略的堆栈变化分析。由于当时堆栈分析并不是很详细,所以我重新推演一遍,以求更精准更细致的理解。

    我使用的代码(test.c)如下:

    #include<stdio.h>
    int add(int x)
    {
        return x+9;
    }
    
    int sec(int x)
    {
        return add(x);
    }
    
    int main(void)
    {
        return sec(15)+9;
    }
    

    经过gcc -S -o test.s test.c -m32的指令反汇编后,得到的文件保存在test.s中,精简后得到如下内容:

    1    add:
    2    	pushl	%ebp
    3    	movl	%esp, %ebp
    4   	movl	8(%ebp), %eax
    5  	    addl	$9, %eax
    6   	popl	%ebp
    7	    ret
    8
    9    sec:
    10	    pushl	%ebp
    11    	movl	%esp, %ebp
    12    	subl	$4, %esp
    13    	movl	8(%ebp), %eax
    14    	movl	%eax, (%esp)
    15    	call	add
    16    	leave
    17    	ret
    18    
    19    main:
    20    	pushl	%ebp
    21    	movl	%esp, %ebp
    22    	subl	$4, %esp
    23    	movl	$15, (%esp)
    24    	call	sec
    25    	addl	$9, %eax
    26    	leave
    27    	ret
    

    设空栈如下:

    从main开始执行,以下为逐句解释:
    最开始的时候ebp和esp都指向标号0的位置

    pushl	%ebp    :ebp入栈,保存当前ebp0,esp-4指向标号1
    movl	%esp, %ebp  :将ebp指向标号1
    subl	$4, %esp    :esp-4,指向标号2
    movl	$15, (%esp) :esp指向的栈中标号2对应的地方存储15
    call	sec :将eip(25)入栈,esp-4指向标号3,跳转至sec执行
    

    接下来执行sec中的代码:

    pushl	%ebp    :将ebp(1)入栈,esp-4指向标号4
    movl	%esp, %ebp  :ebp指向标号4
    subl	$4, %esp    :esp-4,指向标号5
    movl	8(%ebp), %eax   :将ebp指向的地址加八对应地址中的数据放入eax,即标号2对应存储数据15,所以(eax)=15
    movl	%eax, (%esp)    :把eax放入esp对应位置,即栈中标号5对应位置
    call	add :将eip(16)入栈,esp-4指向标号6,跳转至add执行
    

    接下来执行add中的代码:

    pushl	%ebp    :ebp(4)入栈,esp-4指向标号7
    movl	%esp, %ebp  :ebp指向标号7
    movl	8(%ebp), %eax   :ebp+8位置中的数据赋给eax,即标号5位置,(eax)=15
    addl	$9, %eax    :eax中数据+9,即15+9=24
    popl	%ebp    :ebp(4)出栈,即ebp指向标号4,esp+4指向标号6
    ret :eip(16)出栈,esp+4指向标号5,跳转至第16行继续执行
    

    接下来又回到sec中继续执行:

    leave   :把ebp赋给esp,即esp指向标号4,ebp(1)出栈,esp+4指向标号3,ebp指向标号1
    ret :eip(25)出栈,esp+4指向标号2,跳转至第25行继续执行
    

    接下来回到main中继续执行:

    addl	$9, %eax    :eax中的数据+9,即24+9=33
    leave   :把ebp赋给esp,即esp指向标号1,ebp(0)出栈,ebp指向标号0,esp+4指向标号0
    ret :此时栈已经空了,恢复最开始的状态,运行结束,最后的结果保存在eax中,为33.
    

    附图三张:

  • 相关阅读:
    C#中 @ 的用法
    ASP.NET页面间传值
    ASP.NET中常用的文件上传下载方法
    把图片转换为字符
    把图片转换为字符
    JavaScript 时间延迟
    Using WSDLs in UCM 11g like you did in 10g
    The Definitive Guide to Stellent Content Server Development
    解决RedHat AS5 RPM安装包依赖问题
    在64位Windows 7上安装Oracle UCM 10gR3
  • 原文地址:https://www.cnblogs.com/20135202yjx/p/5220953.html
Copyright © 2011-2022 走看看