zoukankan      html  css  js  c++  java
  • Linux操作系统分析之计算机是怎样工作的

                                               SA****6343  孙洪菠 信息安全

    一、C程序的编译过程

    1.1 C程序的编译过程:

        

                            GCC接受example.c作为输入,最后生成可执行代码example的看似简单的流程所经历的复杂步骤

      编译预处理:读取c源程序,对其中的伪指令(以#开头的指令)和特殊符号进行处理;

      编译阶段:通过词法分析和语法分析,在确认所有的指令都符合语法规则后,将其翻译成等价的中间代码表示或汇编代码;

      汇编阶段:把汇编代码翻译成目标机器指令;

      链接:将有关的目标文件彼此连接。

    1.2 源文件Example.c

     1 //Example.c
     2 
     3 int g(int x)
     4 {
     5     return x + 3;
     6 }
     7 
     8 int f(int x)
     9 {
    10     return g(x);
    11 }
    12 
    13 int main()
    14 {
    15     return f(8)+1;
    16 }


    1.3 预处理后的程序Example.cpp

      命令:gcc -E -o Exmple.cpp example

     1 # 1 "Example.c"
     2 # 1 "<built-in>"
     3 # 1 "<command-line>"
     4 # 1 "Example.c"
     5 
     6 
     7 int g(int x)
     8 {
     9  return x + 3;
    10 }
    11 
    12 int f(int x)
    13 {
    14  return g(x);
    15 }
    16 
    17 int main()
    18 {
    19  return f(8)+1;
    20 }

    1.4 编译后的汇编程序Example.s

      命令:gcc -x  cpp-output -S -o example.s example.cpp 或者 gcc -S -o Example.c Example.c

     1     .file    "Example.c"
     2     .text
     3 .globl g
     4     .type    g, @function
     5 g:
     6     pushl    %ebp
     7     movl    %esp, %ebp
     8     movl    8(%ebp), %eax
     9     addl    $3, %eax
    10     popl    %ebp
    11     ret
    12     .size    g, .-g
    13 .globl f
    14     .type    f, @function
    15 f:
    16     pushl    %ebp
    17     movl    %esp, %ebp
    18     subl    $4, %esp
    19     movl    8(%ebp), %eax
    20     movl    %eax, (%esp)
    21     call    g
    22     leave
    23     ret
    24     .size    f, .-f
    25 .globl main
    26     .type    main, @function
    27 main:
    28     leal    4(%esp), %ecx
    29     andl    $-16, %esp
    30     pushl    -4(%ecx)
    31     pushl    %ebp
    32     movl    %esp, %ebp
    33     pushl    %ecx
    34     subl    $4, %esp
    35     movl    $8, (%esp)
    36     call    f
    37     addl    $1, %eax
    38     addl    $4, %esp
    39     popl    %ecx
    40     popl    %ebp
    41     leal    -4(%ecx), %esp
    42     ret
    43     .size    main, .-main
    44     .ident    "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
    45     .section    .note.GNU-stack,"",@progbits

    1.5 汇编成目标代码Example.o

      命令:gcc –x assembler –c  example.s -o example.o 或者 gcc –c example.c -o example.o

    1.6 连接成二进制可执文件Example

      命令:gcc -o example  example.o 或者 gcc -o  example  example.c

    1.7 执行

      命令:./Example

    二、汇编代码在cpu上执行过程中,堆栈的变化

    汇编代码Example.s在cpu上执行过程中,堆栈如何实现函数调用和返回的?

      三条特殊的汇编指令对应的动作:

    call 0x12345 :    pushl %eip(*);

            movl  $0x12345 , %eip(*)

    leave:                movl %ebp , %esp;

            popl %ebp

    ret:                   pop %eip(*)

     在参考了《程序员自我修养》内存一章的绘图之后,我对上诉汇编代码的做如下分析:  

      虚线指向该指令执行后的栈状态,实线表示程序的跳转情况。

      图中SS段的Initialize代表堆栈中框架的建立,对应的两条汇编语句为:push %ebp  ;

                                          mov %esp , %ebp .

      ebp1,ebp2,ebp3 分别表示 main栈、f栈、g栈的栈底指针。

     

                                                             函数的执行过程中堆栈的变化

    三、计算机是如何工作的

      单任务计算机是怎样工作的:计算机的最小模型由cpu和内存组成,对于单任务,计算机先将机器码加载入内存,然后控制器将eip所指向的内容取出即取指,然后顺序执行。执行过程中遇到控制指令,可能跳转。在指令执行过程中,如果遇到函数调用,要借助堆栈来实现,先将调用栈基地址压入堆栈,再压入调用函数的返回地址(下一条指令的地址即当前eip中的内容),此时的栈顶esp作为被调用函数栈的栈底ebp1,之后进入被调用函数继续执行。函数返回时栈的操作是相反的过程。通常函数的返回值由eax寄存器来保存。

      多任务计算机是怎样工作的:多任务的顺利工作要借助中断,进程间调度机制时间片轮转方法等来实现多任务在计算机上工作,在多任务计算机工作过程中,由于要在多个任务间进行切换,所以由单任务计算机工作中函数调用得到启发。多任务的切换类似于单任务中函数的调用。在各个任务之间进行切换之前,要保存前一个任务的栈顶,eip,标志位等信息以及保护现场,以保证该任务再次获得cpu时能够继续执行。就像单任务工作时函数调用后能正常返回继续去执行调用函数下一条指令一样。 

  • 相关阅读:
    基于perl的网络爬虫
    ios cell展示可滑动的图片
    iOS计算字符串的宽度高度
    swift水波效果
    iOS添加另一个控制器的时候要注意啊
    swift隐藏显示导航栏的底线
    swift集成alamofire的简单封装
    tableview详细介绍
    xmpp xml基本语义
    xmpp SASL 定义
  • 原文地址:https://www.cnblogs.com/SA226343/p/3082311.html
Copyright © 2011-2022 走看看