刘蔚然 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

WEEK ONE(2.22——2.28)计算机是如何工作的?

【基本的汇编程序工作原理】

SECTION 1 存储程序计算机

1.1冯诺依曼体系结构:即具有存储程序的计算机体系结构

目前大多数拥有计算和存储功能的设备(智能手机、平板、计算机等)其核心构造均为冯诺依曼体系结构

  1. 从硬件来看

    • CPU与内存通过主线连接,CPU上的IP(可能是16、32、64位)总指向内存的某一块区域;IP指向的CS(代码段)也在内存中;CPU总是执行IP指向的指令。
  2. 从软件来看
    • API(应用程序编程接口,与编程人员)与ABI(程序与CPU的借口界面) 是两个比较重要的软件接口

1.2 课件4/21

关于ABI:指令编码;指令中涉及的寄存器布局;大多数指令可以直接访问内存

1.3 课件5/21

(E代表32位系统)EIP在CPU执行完一条指令之后自加一(自动加一条指令,而不是一个字节或是32位),当然也可以被其它指令,如CALL,RET等修改

SECTION 2 x86汇编基础

2.1 x86(32位)的寄存器中,低16位作为16位register

2.2 关于堆栈段寄存器

EBP(堆栈基址寄存器);ESP(堆栈顶指针寄存器)。上述两个寄存器较为频繁地使用于汇编程序中

2.3 关于代码段寄存器

CPU实际取指令的时候通过cs:eip来描述

2.4 64位CPU

其实与32位在核心机制上差别不大,64位的机器中,寄存器以RXX表示

2.5 常见汇编指令

  1. 后缀的b,w,l,q分别代表8,16,32,64位
  2. 以%标识的寄存器寻址不与内存“打交道”
  3. 直接寻址&立即数寻址
    1. movl $0x123,%eax —— %eax=0x123
    2. movl 0x123,%eax —— 立即数是以$开头的十六进制数值。直接访问指定的内存地址(0x123)中的数据然后赋给%eax
  4. 变址寻址

    movl 4(%ebx),%edx//edx = *(inet_32 *)(ebx+4),即ebx的值加4之后作为一个地址,将其指向的数据赋给%edx
  5. 大多数指令都可以直接访问内存地址
  6. Linux使用的A&T汇编格式与Intel汇编略有不同
  7. 几条重要的汇编指令

2.6汇编小程序练习

以上图中的片段1和3为例完成堆栈变化图:

SECTION 3 汇编一个简单的C程序

3.1 将C代码编译成汇编代码

  • 将代码在实验楼环境中(64位)保存之后,建议使用 -m32将其编译为32位的汇编代码
  • 具体如下:

     gcc -S -o main.s main.c -m32
  • 关于leave指令
    • leave指令与enter指令一起相当于两条宏指令
    • enter指令相当于在原来的堆栈上再建一个新的空堆栈【因为将栈底指针%ebp挪到和栈顶指针相同的位置了】
    • leave指令与enter相反,相当于撤销函数调用堆栈【把栈顶指针提上来,则撤消了该栈】
  • 函数调用堆栈是由逻辑上多个堆栈叠加起来的。
  • 函数的返回值默认用%eax存储,然后返回给上一级函数。

3.2 练习2

【分析】

  1. 从main函数的堆栈变化开始看,可以发现堆栈中填充了8;猜想8可能是主函数传给g(x)的参数;
  2. 调到g后,可以看到先将8传给了%eax;然后再加上了8,紧接着弹栈;猜想应该是x+8;
  3. 主函数又减去了8.这样得到的是x+8-8;
  4. 函数应该如下:

    int g(int x)
    {
    return x+8;
    }
    int main(void)
    {
    return g(8)-8;
    }

实验部分

  • 实验步骤

  • 实验代码

  • 代码汇编结果

add:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
addl $6, %eax
popl %ebp
ret
f:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl 8(%ebp), %eax
movl %eax, (%esp)
call add
leave
ret
main:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl $6, (%esp)
call f
addl $1, %eax
leave
ret
  • 分析(堆栈变化过程图解)

总结

理解“计算机是如何工作的”?

【理解】

我认为,首先需要明确的一点就是:计算机并不“聪明”;相反的是,计算机十分“笨拙”。越是简洁通用的规则(哪怕代价是需要很多的重复计算)越能够让计算机充分发挥其优势——见字面意思,即“计算(compute)”。

  1. 计算机的硬件设施部分,就如第一讲中讲到的那样,除了核心CPU之外,还有寄存器、高速缓存、主存乃至外存这样种类繁多的存储设备。存储设备(这也是冯 诺依曼体系结构的一个重要支点)根本目的就是为CPU服务,存储各种各样的、区分轻重缓急的数据;
  2. 有了上面的硬件基础,计算机的工作过程就集中在了CPU和为其传输数据的地址总线上。各种各样的I/O设备传来的信息、计算机内置的各种程序(比如一些规则、保障性机制)甚至于网络上传播的木马病毒……形形色色的data与code集合都要整合成一条条指令——还是那句话,计算机很“笨拙”,它(CPU)执行的最底层的操作就是N种指令而已;
  3. 计算机的这些指令的执行过程就如同汇编程序中显示的那样,CPU兢兢业业地往各种寄存器中填入数据、跳转或者撤销、释放……这一系列的基本操作(当然还要有硬件配合)在极短的时间完成,未来还会将时间进一步缩短。然后,不可思议的事情就这么发生了:我们可以在计算机中进行闪电般的运算、将各种媒体形式传输到网络上……然而,这些的基础都将追溯到这些0101串中。

《Linux内核分析》第一周 计算机是如何工作的?的更多相关文章

  1. Linux内核分析第一周——计算机是如何工作的

    冯诺依曼体系结构 核心思想 1.冯诺依曼是:数字计算机的数制采用二进制:计算机应该按照程序顺序执行. 2.采用二进制作为计算机数值计算的基础,以0.1代表数值.不采用人类常用的十进制计数方法,二进制使 ...

  2. linux内核分析 第一周 计算机是如何工作的 20125221银雪纯

    我使用的c语言代码是: int g(int x) { return x + 1; } int f(int x) { return g(x); } int main(void) { return f(6 ...

  3. LINUX内核分析第一周学习总结——计算机是如何工作的

    LINUX内核分析第一周学习总结——计算机是如何工作的 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course/ ...

  4. Linux内核分析第一周学习博客 --- 通过反汇编方式学习计算机工作过程

    Linux内核分析第一周学习博客 通过反汇编方式学习计算机工作过程 总结: 通过这次对一个简单C程序的反汇编学习,我了解到计算机在实际工作工程中要涉及大量的跳转指针操作.计算机通常是顺序执行一条一条的 ...

  5. linux内核分析第一周学习笔记

    linux内核分析第一周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...

  6. Linux内核分析第二周--操作系统是如何工作的

    Linux内核分析第二周--操作系统是如何工作的 李雪琦 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course ...

  7. 《Linux内核分析》 之 计算机是如何工作的

    [李行之原创作品 转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] <Linux内 ...

  8. Linux内核分析——第一周学习笔记20135308

    第一周 计算机是如何工作的 第一节 存储程序计算机工作模型 1.冯·诺依曼结构模型:冯·诺依曼结构也称普林斯顿结构,是一种将程序指令存储器和数据存储器合并在一起的存储器结构.程序指令存储地址和数据存储 ...

  9. Linux内核分析第一周学习总结:计算机是如何工作的?

    韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.冯诺依曼体系 ...

  10. Linux内核及分析 第一周 计算机是如何工作的?

    C语言代码: int g(int x) { return x + 5; } int f(int x) { return g(x); } int main(void) { return f(5) + 1 ...

随机推荐

  1. Shell 编程基础之变量和环境变量

    一.变量赋值和引用 Shell 编程中,使用变量无需事先声明,同时变量的命名不惜遵循如下规则: 首个字符必须为字母(a-z,A-Z)或者_ 变量名中间不能有空格,可以使用_连接 不能使用其他表达符号 ...

  2. uva 1339

    Ancient Roman empire had a strong government system with various departments, including a secret ser ...

  3. Leetcode Reverse Words in a String

    Given an input string, reverse the string word by word. For example,Given s = "the sky is blue& ...

  4. 设置 tableview 的背景 颜色 和清空

    表示图中Cell默认是不透明的,那么在设置表示图的背景颜色和图片时通常是看不到的 1.给tableView设置背景view UIImageView *backImageView=[[UIImageVi ...

  5. ACM: 继续畅通工程-并查集-最小生成树-解题报告

    继续畅通工程 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Descri ...

  6. 51nod百度之星2016练习赛

    今天看了看51nod发现有这样一个练习赛,就做了做.因为实力太弱想不出E题,各位神犇勿D. (5.26UPD:E题想粗来了) A 区间交 不难发现若干线段[li,ri]的交就是[max(li),min ...

  7. OSG中的HUD

    OSG中的HUD 所谓HUD节点,说白了就是无论三维场景中的内容怎么改变,它都能在屏幕上固定位置显示的节点. 实现要点: 关闭光照,不受场景光照影响,所有内容以同一亮度显示 关闭深度测试 调整渲染顺序 ...

  8. 浅析-博客Ping服务

    简介:PING服务是博客站点向博客目标网站.搜索引擎等发出的博客内容更新通知服务,然后博客目标网站.搜索引擎就会及时的索引.收录以及传播您的博客内容. PING原理 PING 服务是博客站点向博客目标 ...

  9. js从身份证号中获取出生日期和性别

    今天,在做移动端的项目中,按照设计稿的要求,是可以让用户自己输入出生日期的,我还很认真的用了刚刚知道的html5表单的日期类型,本想着终于不用日期插件就可以实现用户选择自己的出生日期了,可结果老大说, ...

  10. bzoj4518: [Sdoi2016]征途--斜率DP

    题目大意:把一个数列分成m段,计算每段的和sum,求所有的sum的方差,使其最小. 由方差*m可以化简得ans=m*sigma(ki^2)-sum[n]^2 很容易得出f[i][j]=min{f[i- ...