张文俊 + 原创作品转载请注明出处 + 《Linux 内核分析》 MOOC 课程

实验要求:

1、总结部分要求阐明自己对“计算机是如何工作的”理解;

2、博客中需要使用实验截图;

实验内容:

1、阐述计算机是如何工作的;

2、分析汇编代码的工作过程中堆栈的变化;

一、冯诺依曼体系结构

冯诺依曼体系结构是现代计算机的基础,现在大多计算机仍是冯诺依曼计算机的组织结构,只是作了一些改进而已,并没有从根本上突破冯体系结构的束缚。

根据冯·诺依曼体系结构构成的计算机,必须具有如下功能:

把需要的程序和数据送至计算机中。

必须具有长期记忆程序、数据、中间结果及最终运算结果的能力。

能够完成各种算术、逻辑运算和数据传送等数据加工处理的能力。

能够根据需要控制程序走向,并能根据指令控制机冯· 诺依曼体系结构器的各部件协调操作。

能够按照要求将处理结果输出给用户。

冯诺依曼体系结构有以下三条特点:

(1)计算机处理的数据和指令一律用二进制数表示。

(2)顺序执行程序。

(3)计算机硬件由运算器、控制器、存储器、输入设备和输出设备五大部分组成。

二、实验代码

源C代码如下:
int g(int x)

{

return x + 5;

}

int f(int x)

{

return g(x);

}

int main(void)

{

return f(21) + 5;

}
通过实验楼的已搭建好的 64 位 Linux 虚拟机环境,采用如下命令编译汇编代码:

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

其中,-S表示生成为汇编代码;

-m32表示生成的汇编程序是32位的;

汇编程序后缀为.s

使用上条命令汇编出的main.s文件代码如下:

    .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 $5, %eax
popl %ebp
.cfi_restore 5
.cfi_def_cfa 4, 4
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 $21, (%esp)
call f
addl $5, %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

其中,实际被程序执行的代码如下:

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

三、汇编代码分析

首先从 main 函数开始:

pushl   %ebp
movl %esp, %ebp

表示将基底指针压栈,然后把栈顶指针的值赋给基底指针。

subl    $4, %esp
movl $21, (%esp)

由于栈是由高地址向低地址扩展,在 32 位操作系统系统上,每个栈元素为 4 个字节,所以栈顶指针减 4表示栈顶指针减了一个单位(即向下拓展一个单位);

同时,采用立即数寻址的方式,把21 存入栈顶指针所指向的位置。

call f

call 指令调用函数 f 执行,

call指令,相当于pushl %eip movl $f, %eip

即:首先将当前 %eip 的值压栈保存,然后将f地址赋给eip。

函数 f 类似于main函数,f继续调用g函数。在g函数中,eax的值要增加5 ,然后 popl 出栈返回到先前函数 f 中 call 指令保存执行指令地址。

addl    $5, %eax
popl %ebp

函数g返回后,函数 f 的下一条指令 leave 相当于:

movl  %ebp, %esp
popl %ebp

它将函数堆栈恢复到当前函数被调用前的状态。

然后执行ret指令,函数返回。

函数 f 返回后,函数 main 的下一条指令将 eax中的值加5,然后再leave恢复堆栈状态,ret返回。

四、总结

计算机的基本工作原理是美籍匈牙利科学家冯`诺依曼于1946年首先提出来的。

其核心是存储程序与控制,即计算机能够自动的完成运算或处理过程的基础是存储程序和程序控制。

计算机之所以能自动,正确的按人们的意图工作,是由于人们事先已把计算机如何工作的程序和原始数据通过输入设备送到计算机的存储器中。

当计算机执行时,控制器就把这些指令一条接一条地从存储器中取出来,加以翻译,并按指令的要求进行相应的操作,直到遇到停止指令或发生计算机无法继续运行的情况为止。

程序中的每一条指令都要求计算机完成一定的操作。一条指令通常由两个部分组成,即地址码(操作码)和操作数。

因为计算机只能识别二进制数,所以每条指令都用二进制编码表示,但直接用二进制编码书写指令不方便,因此常用十六进制形式表示。

五、实验截图

“Linux内核分析”实验一报告的更多相关文章

  1. 【MOOC EXP】Linux内核分析实验八报告

    程涵  原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 进程的切换和系统的一般执行过程 知识点 ...

  2. 【MOOC EXP】Linux内核分析实验七报告

    程涵  原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 可执行程序的装载 知识点梳理 一.预处 ...

  3. 【MOOC EXP】Linux内核分析实验六报告

    程涵  原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 进程的描述和进程的创建 知识点梳理: ...

  4. “Linux内核分析”实验二报告

    张文俊 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.第二周学习内 ...

  5. “Linux内核分析”实验三报告

    构造一个简单的Linux系统 张文俊+原创作品转载请注明出处+<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-10000290 ...

  6. 【MOOC EXP】Linux内核分析实验一报告

    程涵  原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000  [反汇编一个简单的C程序]   实验 ...

  7. 【MOOC EXP】Linux内核分析实验二报告

    程涵  原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000  [操作系统是如何工作的]   教学内 ...

  8. 【MOOC EXP】Linux内核分析实验三报告

     程涵  原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 [跟踪分析Linux内核的启动过程] ...

  9. 【MOOC EXP】Linux内核分析实验四报告

    程涵  原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 [使用库函数API和C代码中嵌入汇编代 ...

随机推荐

  1. 2018.09.01 09:22 Exodus

    Be careful when writing in the blog garden. Sometimes you accidentally write something wrong, and yo ...

  2. 在Linux服务器上运行Jupyter notebook server教程

    在Linux服务器上运行Jupyter notebook server教程 很多deep learning教程都推荐在jupyter notebook运行python代码,方便及时交互.但只在本地运行 ...

  3. cookie的详解

    cookie是如何出生的 由于HTTP协议是无状态的,而服务器端的业务必须是要有状态的.Cookie诞生的最初目的是为了存储web中的状态信息,以方便服务器端使用.比如判断用户是否是第一次访问网站.目 ...

  4. Spring-AOP SpringBoot自动配置和启动Spring AOP

    SpringBoot 会使用 @Conditional* 注解来进行判断是否需要自动启动 AOP,如果 classpath 下有 spring-aop 的 jar 和有 EnableAspectJAu ...

  5. Python os.walk() 方法

    #coding=utf-8 import os #(dirpath, dirnames, filenames)[文件夹路径, 文件夹名字, 文件名] def file_name(file_dir): ...

  6. JAVA框架 Spring 和Mybatis整合(传统dao)

    一:我们使用spring处理service,mybaits处理dao层. 二:导入jar包 pom.xml文件内容: <?xml version="1.0" encoding ...

  7. DM9161 和 STM32F107 和 FreeRTOS 和 LWIP

    1.首先移植 FreeRTOS到  107上 可以正常运行. 可以到群下载移植好的,文件名称:STM32F107VC+FreeRTOS V8.2.3+kfifo(巧夺天工)! 2.第二步 :ST 官方 ...

  8. timestamp 字段

    项目中由于需求设计,数据库中需要一个timestamp时间戳类型的字段来作为区别数据添加和修改的标识.由于timestamp在SQL SERVER 2005数据库中,不可为空的timestamp类型在 ...

  9. MySQL学习笔记04 插入中文时出现ERROR 1366 (HY000)

    1 环境: MySQL Server 6.0  命令行工具 2 问题 :  插入中文字符数据出现如下错误: ERROR 1366 (HY000): Incorrect string value: '\ ...

  10. Scala_方法和函数

    方法的定义 def functionName([参数列表]) : [return type] = { function body return [] } 如果没有=和{}包裹的方法体,那么该方法被隐式 ...