Linux内核分析(一)之“愚蠢”的计算机

1.冯诺依曼体系结构

不远的将来,计算机的发展就会迈入一个新的时代,一个属于人工智能(Artificial Intelligence)的时代。哪怕是今天今天计算机是显得如此聪明,譬如前些时间比较火的阿尔法狗。哪怕是普通的计算机也仿佛对你了如执掌,他知道你喜欢吃什么,知道你喜欢买什么,知道你喜欢看什么。立足现在,回溯过去,正如老师在课程中引荐的资治通鉴的一句话:天下难事必作于易,天下大事必作于细。我们从计算机的里子出发,看一看计算机的底部是How to work。

哪怕是现如今最先进的计算机,依然无法脱离冯-诺依曼体系结构。如下图
冯诺依曼

CPU中的寄存器从内存中顺序的执行代码段。而且计算机是采用二进制的,这意味着它们只认识0和1。如此看来计算机是非常之“愚蠢”的。它们的原理是如此简单,但是正如开篇所讲:天下难事必作于易。许多简简单单的事组合在一起便成了复杂。

这里写图片描述

2.汇编简介

详情请度娘

3.实验结果分析

gcc –S –o main.s main.c -m32
用该命令将main.c代码编译成汇编代码

#include<stdio.h>
int main()
{
  return f(10) + 1;
}
int g(int x)
{
  return x + 100;
}

int f(int x)
{
  return g(x);
}

编译后的汇编代码如下
这里写图片描述

删除点号后的内容如下

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

首先,我们来分析这段汇编代码。

  1 main:                                                                    
  2     pushl   %ebp          将ebp的地址压入堆栈,同时esp向下移动一个位置                                           
  3     movl    %esp, %ebp    将ebp栈底地址移动至esp栈顶位置                                                                                          
  4     andl    $-16, %esp    预留局部变量的栈空间                                               
  5     subl    $16, %esp     预留局部变量的栈空间                                           
  6     movl    $10, (%esp)   将10的值置入esp地址中                                           
  7     call    f             调用f函数(将当前的eip=8放入堆栈当中,同时
                              eip置为f函数的地址位置,eip=19*此时将跳至
                              执行f函数19号的位置                                              
  8     addl    $1, %eax      eax+=1,eax=110+1=111                                              
  9     leave                 参考25                                               
 10     ret                   返回eax=111的值
 11 g:                         *创建g函数的堆栈                                               
 12     pushl   %ebp           参考指标2                                              
 13     movl    %esp, %ebp     参考指标3                                              
 14     movl    8(%ebp), %eax  ebp变址寻址两个位置,取出里面的值赋给eax=10                                             
 15     addl    $100, %eax     eax+=100,eax=110                                              
 16     popl    %ebp           弹出ebp,使其指向当前堆栈中ebp所指的地址位
                               置                                              
 17     ret                    esp上移一位,eip指向25的位置                                           
 18 f:                                   *创建f函数的堆栈                                    
 19     pushl   %ebp                     参考指标2                                    
 20     movl    %esp, %ebp               参考指标3                                  
 21     subl    $4, %esp                 esp下移一个位置                                  
 22     movl    8(%ebp), %eax            ebp变址寻址两个位置,取出指针 
                                         ebp中的值,将其放入eax累加器
                                         中,eax=1023     movl    %eax, (%esp)             将eax的值放入esp所指的堆栈空间                                  
 24     call    g                        调用g函数(将当前的eip=25压入堆
                                         栈,同时eip置为12*此时跳至执
                                         行指标12号的位置                                    
 25     leave                            movl %ebp,%esp 参考3
                                         popl %ebp   参考16                            
 26     ret                              esp上移一位,eip指向8

汇编分析结果
图示附件

Linux内核分析课程链接
writen by 江明星

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值