程序人生-Hello’s P2P

打印 上一主题 下一主题

主题 768|帖子 768|积分 2304

摘  要

本文完备描述了一个简单的应用程序在Linux系统下运行的整个生命周期。从源程序作为起点,履历编译、链接,一直到加载、运行,再到终止、回收。这个过程涉及到底层硬件及利用系统的多个方面,完备体现了在当代盘算机下一个程序执行的全过程。整个探索的过程充分体现了整个课程丰富的知识框架。

关键词:生命周期;内存管理;编译;                           









目  录


第1章 概述............................................................................................................. - 4 -
1.1 Hello简介...................................................................................................... - 4 -
1.2 情况与工具..................................................................................................... - 4 -
1.3 中间结果......................................................................................................... - 4 -
1.4 本章小结......................................................................................................... - 4 -
第2章 预处理......................................................................................................... - 5 -
2.1 预处理的概念与作用..................................................................................... - 5 -
2.2在Ubuntu下预处理的下令.......................................................................... - 5 -
2.3 Hello的预处理结果剖析.............................................................................. - 5 -
2.4 本章小结......................................................................................................... - 5 -
第3章 编译............................................................................................................. - 6 -
3.1 编译的概念与作用......................................................................................... - 6 -
3.2 在Ubuntu下编译的下令............................................................................. - 6 -
3.3 Hello的编译结果剖析.................................................................................. - 6 -
3.4 本章小结......................................................................................................... - 6 -
第4章 汇编............................................................................................................. - 7 -
4.1 汇编的概念与作用......................................................................................... - 7 -
4.2 在Ubuntu下汇编的下令............................................................................. - 7 -
4.3 可重定位目标elf格式................................................................................. - 7 -
4.4 Hello.o的结果剖析...................................................................................... - 7 -
4.5 本章小结......................................................................................................... - 7 -
第5章 链接............................................................................................................. - 8 -
5.1 链接的概念与作用......................................................................................... - 8 -
5.2 在Ubuntu下链接的下令............................................................................. - 8 -
5.3 可执行目标文件hello的格式.................................................................... - 8 -
5.4 hello的假造地点空间.................................................................................. - 8 -
5.5 链接的重定位过程分析................................................................................. - 8 -
5.6 hello的执行流程.......................................................................................... - 8 -
5.7 Hello的动态链接分析.................................................................................. - 8 -
5.8 本章小结......................................................................................................... - 9 -
第6章 hello进程管理................................................................................... - 10 -
6.1 进程的概念与作用....................................................................................... - 10 -
6.2 简述壳Shell-bash的作用与处理流程..................................................... - 10 -
6.3 Hello的fork进程创建过程..................................................................... - 10 -
6.4 Hello的execve过程................................................................................. - 10 -
6.5 Hello的进程执行........................................................................................ - 10 -
6.6 hello的异常与信号处理............................................................................ - 10 -
6.7本章小结....................................................................................................... - 10 -
第7章 hello的存储管理................................................................................ - 11 -
7.1 hello的存储器地点空间............................................................................ - 11 -
7.2 Intel逻辑地点到线性地点的变换-段式管理............................................ - 11 -
7.3 Hello的线性地点到物理地点的变换-页式管理....................................... - 11 -
7.4 TLB与四级页表支持下的VA到PA的变换............................................. - 11 -
7.5 三级Cache支持下的物理内存访问.......................................................... - 11 -
7.6 hello进程fork时的内存映射.................................................................. - 11 -
7.7 hello进程execve时的内存映射.............................................................. - 11 -
7.8 缺页故障与缺页克制处理........................................................................... - 11 -
7.9动态存储分配管理....................................................................................... - 11 -
7.10本章小结..................................................................................................... - 12 -
第8章 hello的IO管理................................................................................. - 13 -
8.1 Linux的IO装备管理方法.......................................................................... - 13 -
8.2 简述Unix IO接口及其函数....................................................................... - 13 -
8.3 printf的实现分析........................................................................................ - 13 -
8.4 getchar的实现分析.................................................................................... - 13 -
8.5本章小结....................................................................................................... - 13 -
结论......................................................................................................................... - 14 -
附件......................................................................................................................... - 15 -
参考文献................................................................................................................. - 16 -



第1章 概述

1.1 Hello简介

P2P:通过在文本编辑器里写下Hello.c的源代码,经过编译器进行预处理、编译、汇编、链接的过程,将源代码翻译成汇编语言,再翻译成机器语言,能够被硬件辨认以及执行相应的指令。接着在面向用户的Shell里,通过创建子进程,调用生成的Hello可执行程序,同时为其分配假造内存以及运行时所占用的时间片,使得程序得以在CPU等硬件上运行。
020:在程序开始运行前不占用任何运行资源;当运行时利用系统为其分配内存空间以及执行时间以及相应的盘算资源;运行结束后,利用系统杀死该进程,回收所有的资源,归于平静。
1.2 情况与工具

硬件情况:12th Gen Intel(R) Core(TM) i7-12700H 2.30 GHz;16.0 GB。
软件情况:Windows 11 64位;VMWare Workstation 17 Player;Ubuntu 23.10。
开发工具:gcc;edb;vim;objdump;readelf;as;ld。
1.3 中间结果

Hello.i:Hello.c文件经过预处理之后生成的源代码;
Hello.s:Hello.i文件经过编译后生成的汇编代码;
Hello.o:Hello.s文件经过汇编后生成的目标文件;
Hello:Hello.s文件在与其他文件进行链接后形成的可执行程序。
1.4 本章小结

       本章节描述了整个大作业的概况。


第2章 预处理

2.1 预处理的概念与作用

预处理指将源代码通过预处理程序翻译成更容易被编译器进行处理的单个文件。比如将调用的头文件(header)全部睁开,将定义的宏(define)进行睁开,在实际编译时编译器只需要对单个文件进行编译。
经过预处理后的程序可以被编译器进行编译生成汇编程序。
2.2在Ubuntu下预处理的下令


通过在源代码所在目录下执行下令gcc -E hello.c -o hello.i,将hello.c预处理。
2.3 Hello的预处理结果剖析

预处理结果前面部分是Hello.c内里涉及到的所有的宏(包罗对头文件的引用,以及嵌套引用)进行睁开之后的结果。所有用井号标注的行为注释,表现在睁开前这部分属于哪个文件的哪个部分。
同时预处理还删除了整个过程中出现的所有注释。
2.4 本章小结

本章节简要介绍了Hello.c程序进行预处理的结果以及作用。
预处理只是简单的文本拼接,经过预处理之后生成的程序仍然是文本文件。但是预处理之后的文件才可以被编译器做进一步处理。

第3章 编译

3.1 编译的概念与作用

编译指经过预处理后的高级语言源代码,通过所处利用系统下编译器的编译利用,将高级语言表述的各种功能逐条描述成汇编语言的过程。
汇编语言贴近于盘算机实际利用的CPU指令,可以按照相应的指令集翻译成对应的机器语言,是编译成可执行程序之前的最后一步利用;同时汇编语言保存了肯定的可读性,开发者尚可根据汇编指令理解程序的运行细节。
3.2 在Ubuntu下编译的下令



3.3 Hello的编译结果剖析

3.3.1 数据存储

       在Hello.c源代码中出现的量有如下几种:

  • 常量,如“用法: Hello 学号 姓名 秒数!\n”、“Hello %s %s\n”等。这些常量被存放在text段,是只读情势的字符串。
  • 变量,如在main函数内定义的i。这些量会在运行时存储在堆栈当中,因此在调用之前栈指针会发生偏移,用于存放这些变量。
  • 参数,如在main函数参数列表里的argc和argv。这些参数会在调用main函数之前压入栈中,不由main函数分配空间,而需要外部程序在调用main函数之前提前放到堆栈当中。
3.3.2 运算符

  • 赋值语句通过mov指令实现;
  • 比较语句通过cmp指令实现;
  • 对地点的解引用,通过对指针所指向的地点进行偏移,并读取此中的数值实现。
3.3.3 判断语句

判断语句通过cmpl和je语句实现。详细来说,cmpl语句会将argc的值与4进行比较,存放进寄存器里;je语句则会根据寄存器当中的结果进行跳转。如果argc和4相称,则会直接跳转到L2;而如果不等,则继续执行下列语句(输出提示并终止程序)。
3.3.4 循环语句

For循环三个内容分别对应着L2、L3、L4最后一部分。先执行L2内的语句进行循环前的初始化,接着跳转进L3判断是否需要执行循环。如果满足条件,就会跳进L4执行循环体内的内容,并在最后执行i++,接着进入L3,云云往复。
3.3.5 函数调用
函数调用主要通过call、leave、ret指令实现。在进行函数调用之前,程序会向堆栈中推入被调用函数所需要利用的参数(对于64位利用系统,若传入的参数数量较少,则会直接利用寄存器用于传参)。接着执行call指令,此时会推入当前代码的行数,并跳转进入被调用函数的片段,而leave指令用于收尾利用还原栈指针,ret指令则是让程序跳转回调用它的代码语句。
3.4 本章小结

本章节介绍了从预处理后的源代码经过编译生成汇编语言的过程。

第4章 汇编

4.1 汇编的概念与作用

汇编指经过编译生成的汇编源码,经过汇编程序根据相应平台的指令集将汇编代码逐条翻译成可被CPU直接辨认的机器码的过程。
经过汇编后的代码已经完全酿成了只可被机器辨认的机器代码,只暴露一些函数接口及全局变量等,不再可读。通过链接上一些须要的文件,程序即可被执行。
4.2 在Ubuntu下汇编的下令




4.3 可重定位目标elf格式



 
4.4 Hello.o的结果剖析


机器语言由二进制01串构成,每条指令由是非不一的01数字进行编码,越常用的指令的编码通常越短。汇编语言由文本写成,根本上逐条描述机器语言的每一条指令,但是汇编语言当中可能会有一些别的助记符号。
在分支转移函数的调用当中,汇编语言会给特定的语段加上暗号,比如jmp .L3 表现跳转到 L3 暗号所在处。但是当汇编语言翻译成机器语言后,利用数就酿成了L3暗号所对应的语句的地点。
4.5 本章小结

本章节简述了编译器将汇编语言翻译成机器语言的过程,简要阐述了机器语言与汇编语言的区别。

第5章 链接

5.1 链接的概念与作用

链接指将一个或多个由编译器或汇编器生成的目标文件外加库,链接为一个可执行文件的过程。
编写程序时可能会调用到一些别的函数,例如系统函数。这些函数所对应的机器码并不在源代码当中,编译完成的目标文件想要执行,就需要与这些外部的目标文件进行链接,进而程序才气调用那些原本不属于自己的函数。通过链接可以大大简化用户编写程序的过程。
5.2 在Ubuntu下链接的下令


5.3 可执行目标文件hello的格式



5.4 hello的假造地点空间

    利用edb加载hello,查看本进程的假造地点空间各段信息,并与5.3对照分析说明。  
5.5 链接的重定位过程分析


两者主要有以下不同:

  • 新增加了诸如puts、printf、sleep等段。这是由于经过动态链接之后这些函数的代码参加到了可执行文件当中;
  • 新增加了诸如.init和.plt等节,这些是程序执行所不可缺少的节。
  • 一些逻辑地点在经过链接之后酿成了假造地点。
重定位的主要方式是,(1)将相同的节合并到一起;(2)在合并之后确定一些先前没有确定下来的地点。
5.6 hello的执行流程


在加载 hello之前,起首调用了/lib/x86_64-linux-gnu/libthread_db.so.1动态链接库。在此之后进入_start函数开始执行hello的主要代码。调用main之前,依次执行了:

  • _init();
  • _frame_dummy();
  • _register_tm_clones();
  • main();


在调用main函数之后,反复调用执行printf函数以及sleep函数。最后依次调用了:

  • __do_global_dtors_aux();
  • deregister_tm_clones ();
  • _fini ();
终极退出程序。
5.7 Hello的动态链接分析



利用readelf查看生成的hello文件,可以发现此中的.got段的起始位置为0x403fd8,大小为0x10。

在程序进行dl_init之前,可以发现got表当中的元素都是0x00。而当进行dl_init之后,got表当中的元素被填上了偏移量,表现程序想要调用这些外部函数需要从哪个地点去寻找。
5.8 本章小结

本章节主要介绍了在hello程序的链接过程,以及在运行时发生的动态链接的过程。

第6章 hello进程管理

6.1 进程的概念与作用

进程是正在运行的程序的实例,一个进程可以向利用系统申请内存及运算资源。执行一个程序的过程,就是利用系统创建并执行一个进程的过程。
进程被用来描述每个程序的运行情况,反映了一个盘算机里正在运行的程序。利用系统可以通过管理这些进程从而实现对不同程序的管理。进程之间也可以发生不同的交互,以实现更复杂的过程。
6.2 简述壳Shell-bash的作用与处理流程

Shell-bash是面向用户的下令窗口。用户通过在shell里输入指令,可以利用盘算机执行不同的指令,以及管理不同的程序进程。用户可以打开Shell,键入指令来开始执行程序,当程序执行完毕后执行的结果会被反馈到Shell上。当关闭Shell之后利用系统会回收所有的资源。
6.3 Hello的fork进程创建过程

Fork进程时,利用系统将会检测用户是否能够创建一个新的进程,若能创建,则会设置该进程的各种信息,并为其分配优先级便于内核进行调度。同时,利用系统会复制及共享当前Shell进程占用的资源,用于执行该子进程。
6.4 Hello的execve过程

当执行execve时,Hello程序编译生成的elf文件将会被装载进当前进程里,覆盖掉原先属于Shell的内存。此时该进程完全交给Hello程序。
6.5 Hello的进程执行

CPU会给每个进程分配对应的时间片,由于CPU的运转效率较高,看上去不同的进程是在同时进行的。下文将Shell进程和Hello进程分别称作A进程和B进程。CPU执行时,会轮番执行这两个进程内的代码。假定当前处于用户态, 并处于A进程被CPU运行的状态。一段时间后,用户态被切换为核心态,系统内核将A进程的寄存器值保存到堆栈中,将B进程原先的寄存器值还原,接着切换回用户态执行进程B。当进程B执行了一段时间后,当前状态再次切换为用户态,系统内核保存B进程的寄存器并装载A进程的寄存器。云云循环往复进行进程的调度,使得用户感觉两个进程在同时进行。
6.6 hello的异常与信号处理

 hello执行过程中会出现哪几类异常,会产生哪些信号,又怎么处理的。
 程序运行过程中可以按键盘,如不绝乱按,包罗回车,Ctrl-Z,Ctrl-C等,Ctrl-z后可以运行ps  jobs  pstree  fg  kill 等下令,请分别给出各下令及运行结截屏,说明异常与信号的处理。

  • 正常执行hello程序:
进程收到的信号:无;
进程收到的异常:

  • 时钟克制:不处理;
  • 系统调用:调用write函数打印字符;
  • 缺页异常:交由缺页异常处理程序。

  • 按下Ctrl+Z利用:
进程收到的信号:SIGSTOP;
进程收到的异常:

  • 处理器克制:不处理;   

    • 执行ps下令:




    • 执行jobs指令:




    • 执行pstree指令:




    • 执行fg指令:




    • 执行kill指令:


6.7本章小结

       本章节简要介绍了hello程序在程序运行过程中对信号以及异常的处理机制,简述了诸如时钟克制、系统调用、缺页异常等异常发生的情况下hello程序的处理机制,也简要说明了hello程序在运行过程中接收到的信号。

第7章 hello的存储管理

7.1 hello的存储器地点空间

假造地点:是由程序产生的由段选择符段内偏移地点组成的地点。这2部分组成的地点并不能直接访问物理内存,而是要通太过段地点的变化处理后才会对应到相应的物理内存地点。例如hello.c当中,在主函数里定义的变量i,它的假造地点可以视作main对应的这一段的偏移量加上i在这一段内偏移地点组成。
逻辑地点:指由程序产生的段内偏移地点。逻辑地点与假造地点二者之间没有明确的边界。hello.c当中变量i的假造地点和逻辑地点可视作相同。
线性地点:指假造地点到物理地点变换的中间层,是处理器可寻址的内存空间(称为线性地点空间)中的地点。程序代码会产生逻辑地点,或者说段中的偏移地点,加上相应段基址就成了一个线性地点。经过段式管理以后,i的地点将会酿成线性地点。
物理地点:指内存中物理单元的集合,他是地点转换的终极地点,进程在运行时执行指令和访问数据最后都要通过物理地点来存取主存。
7.2 Intel逻辑地点到线性地点的变换-段式管理

段式管理的根本思想是把程序按内容或过程函数关系分成段,每段有自己的名字。一个用户作业或者进程所包罗的段对应一个二维线性假造空间,也就是一个二维假造存储器。段式管理程序以段为单元分配内存,然后通过地点映射机构把段式假造地点转换为实际内存物理地点。
Hello.c当中每个函数对应着线性地点上的一个段,每个段所占据的内存也是一个段。每个函数内的变量地点会被映射到线性地点上面。
7.3 Hello的线性地点到物理地点的变换-页式管理

页式管理的根本原理是将各进程的假造空间分别为多少个长度相称的页。把内存空间按页的大小分别为片或者页面,然后把页式假造地点与内存地点建立逐一对应的页表,并用相应的硬件地点转换机构来解决离散地点变换问题。页式管理接纳请求调页和预调页技能来实现内外存存储器的统一管理。
Hello.c当中所有变量所占用的地点可以视作一整条线性地点。线性地点的总长度可能凌驾内存硬件所能担当的地点的长度。这条地点会被利用系统分成多少页,每一页上的地点又会在被利用时被映射到物理地点。
7.4 TLB与四级页表支持下的VA到PA的变换

TLB:页表常驻内存,地点翻译时MMU需要去内存中访问,为减少这样的开销,MMU中包罗了一个关于PTE的小缓存,称为翻译后备缓冲器(TLB)。
多级页表:将页表分为多个层级,以减少内存要求。
由TLBI,访问TLB中的某一组,遍历该组中的所有行,若找到一行的tag等于TLBT,且有用位valid为1,则缓存掷中,该行存储的即为PPN;否则缓存不掷中,需要到页表中找到被请求的块替换原TLB表项中的块。
多级页表的访问:缓存不掷中后,VPN被解释成从低位到高位的等长的4段,从高地点开始,第一段VPN作为第一级页表的索引,用以确定第二级页表的基址;第二段VPN作为第二级页表的索引,用以确定第三级页表的基址;第三段VPN作为第三级页表的索引,用以确定第四级页表的基址;第四段VPN作为第四级页表的索引,若该位置的有用位为1,则第四级页表中的该表项存储的是所需要的PPN的值。
7.5 三级Cache支持下的物理内存访问

CPU将物理地点解释为三部分:CT(缓存标记),CI(组索引),CO(块偏移)。
起首根据组索引CI,遍历缓存中对应组的所有行,若找到一行的tag等于CT,且标记位valid为1,则缓存掷中(hit),根据CO(块偏移)读取块中对应的数据;否则缓存不掷中。
若缓存不掷中,则向下一级缓存中查找数据(一级Cache、二级Cache、三级Cache、主存、磁盘)。找到数据之后,开始进行行替换。若该组中有空行,那就将数据缓存至这个空行,并设置tag和valid位;若该组中没有空行,根据一些计谋来决定驱逐哪一行,如最不常利用(LFU)计谋和最近最少利用(LRU)计谋。LFU计谋会替换过去某个时间段内访问次数最少的那一行,LRU计谋会替换最后一次访问时间最长远的那一行。
7.6 hello进程fork时的内存映射

当前进程调用fork函数时,内核会为新进程创建各种数据结构,并分配给它一个唯一的PID。为了给这个新流程创建假造内存,它创建了当前流程的mm_struct,区域结构和页表的原样副本。它将两个进程中的每个页面标记为只读,并将两个进程中的每个区域结构标记为私有的写时复制。
当fork在新进程中返回时,新进程现在的假造内存刚好和调用fork时存在的假造内存完全相同。当这两个进程的任一个后来进行写利用时,写时复制机制就会创建新页面,因此,也就为每个进程保持了私有地点空间的抽象概念。
7.7 hello进程execve时的内存映射

execve函数在当前进程的上下文中加载并执行可执行目标文件hello 中的程序。加载并运行hello 需要执行以下步调:

  • 删除已存在的用户区域。删除当前进程假造地点的用户部分中的已存在的区域结构。
  • 映射私有区域。为新程序的代码、数据、bss 和栈区域创建新的区域结构,所有这些新的区域都是私有的、写时复制的。代码和数据区域被映射为hello 文件中的.text 和.data 区,bss 区域是请求二进制零的,映射到匿名文件,其大小包罗在hello 中,栈和堆地点也是请求二进制零的,初始长度为零。
  • 映射共享区域。hello 程序与共享对象libc.so 链接,libc.so 是动态链接到这个程序中,然后再映射到用户假造地点空间中的共享区域内。
  • 设置程序计数器(PC),execve 做的最后一件事情就是设置当前进程上下文的程序计数器,使之指向代码区域的入口点。
7.8 缺页故障与缺页克制处理

缺页故障是一种常见的故障,当指令引用一个假造地点,在MMU 中查找页表时发现与该地点相对应的物理地点不在内存中,因此必须从磁盘中取出的时候就会发生故障。
缺页克制处理:缺页处理程序是系统内核中的代码,选择一个牺牲页面,如果这个牺牲页面被修改过,就将其写回,然后换入新的页面并更新页表。缺页处理程序返回时,CPU重新启动引起缺页的指令,这条指令再次发送 VA 到 MMU,这次 MMU 就能正常翻译 VA 了。
7.9动态存储分配管理

动态内存分配器维护着一个进程的假造内存区域,称为堆。分配器将堆视为一组不同大小的块的集合来维护。每个块就是一个一连的假造内存片,要么是已分配的,要么是空闲的。已分配的块显式地保存为供应用程序利用。空闲块可用来分配。空闲块保持空闲,直到它显式地被应用所分配。一个已分配的块保持已分配状态,直到它被开释,这种开释要么是应用程序显式执行的,要么是内存分配器自身隐式执行的。
7.10本章小结

本章主要介绍了hello的存储器地点空间、intel的段式管理、hello的页式管理,介绍了VA 到PA 的变换、物理内存访问,还介绍了hello 进程 fork 时的内存映射、execve 时的内存映射、缺页故障与缺页克制处理、动态存储分配管理。
第8章 hello的IO管理


8.1 Linux的IO装备管理方法

装备的模型化:所有的IO装备都被模型化为文件装备管理。
装备管理:所有的输入和输出都被当做对相应文件的读和写来执行,这种将装备映射为文件的方式,答应Linux内核引出一个简单,低级的应用接口,称为Unix I/O。
8.2 简述Unix IO接口及其函数

8.2.1接口
打开文件:一个应用程序通过要求内核打开相应的文件,来说明它想要访问一个I/O装备,内核返回一个小的非负整数,叫做描述符,它在后续对此文件的所有利用中标识这个文件,内核记录有关这个打开文件的所有信息。
改变当前文件位置:对于每个打开的文件,内核保持着一个文件位置p,初始为0,这个文件位置是从文件开头起始的字节偏移量,应用程序能够通过执行seek,显式地将改变当前文件位置p。
读写文件:一个读利用就是从文件复制肯定个数的字节到内存,从当前文件位置p开始,然后将p增加到p+n。假设当前打开的文件的大小为m字节,当p>=m时执行读利用就会触发EOF。而写利用则是将n个字节写入到文件当中去,同时将p修改为p+n。
关闭文件:当应用完成了访问,它就通知内核关闭这个文件,并开释文件打开时创建的数据结构,并将这个描述符恢复到可用的描述符池中去。
8.2.2 函数
int open(char* filename, int flags, mode_t mode):打开文件。进程通过调用open函数来打开一个存在的文件或是创建一个新文件。open函数将filename转换为一个文件描述符,并且返回描述符数字,返回的描述符总是在进程中当前没有打开的最小描述符,flags参数指明了进程筹划怎样访问这个文件,mode参数指定了新文件的访问权限位。
int close(fd):关闭文件。fd是需要关闭文件的描述符。
size_t read(int fd, void *buf, size_t n):从描述符为fd的当前位置最多赋值n个字节到内存buf的位置,返回值为实际传送的字节数量。
size_t wirte(int fd, const void *buf, size_t n):从内存位置buf复制至多n个字节到描述符为fd的当前文件位置。
8.3 printf的实现分析

从vsprintf生成表现信息,到write系统函数,到陷阱-系统调用 int 0x80或syscall等。
字符表现驱动子程序:从ASCII到字模库到表现vram(存储每一个点的RGB颜色信息)。
表现芯片按照刷新频率逐行读取vram,并通过信号线向液晶表现器传输每一个点(RGB分量)。
8.4 getchar的实现分析

异步异常-键盘克制的处理:键盘接口得到一个代表该按键的键盘扫描码,同时同时产生克制请求,请求抢占当前进程运行键盘克制子程序,克制子程序先从键盘接口取得该按键的扫描码,然后将该按键扫描码转换成ASCII码,保存到系统的键盘缓冲区之中。
8.5本章小结

本章主要介绍了 Linux 的 IO 装备管理方法、Unix IO 接口及其函数,了解了 printf 函数和 getchar 函数的实现。

结论

Hello程序依次经过了预处理、编译、汇编、链接形成了可执行程序。
接着,用户打开Shell程序,创建新的进程,并且执行Hello程序。此时Shell进程将会利用fork函数创建子进程,同时利用execve函数将该进程的内存等交由hello程序运行。
在执行过程中,Hello 会向利用系统申请内存。Hello当中每个变量的地点会依次经过段式管理和页式管理,从逻辑地点转变为线性地点,再转变为物理地点。在此过程中会涉及到多级页表以及多级Cache对内存进行管理。
再执行过程中,Hello还会涉及到克制以及信号。例如,在调用sleep函数时会产生系统克制,在页缺失的时候会发生缺页克制。这些克制使得Hello程序可以实现各种功能。同时Hello还会受到Shell进程发给它的信号。
在Hello程序执行时,还会与用户发生交互。例如,用户向程序当中键入笔墨、Hello向屏幕上打印笔墨,这些都涉及到Linux系统底层的IO交互。通过不同函数的协同作用Hello得以完成IO交互。

附件

Hello.i:Hello.c文件经过预处理之后生成的源代码;
Hello.s:Hello.i文件经过编译后生成的汇编代码;
Hello.o:Hello.s文件经过汇编后生成的目标文件;
Hello:Hello.s文件在与其他文件进行链接后形成的可执行程序。

参考文献

[1]  林来兴. 空间控制技能[M]. 北京:中国宇航出版社,1992:25-42.
[2]  辛希孟. 信息技能与信息服务国际研讨会论文集:A集[C]. 北京:中国科学出版社,1999.
[3]  赵耀东. 新时代的工业工程师[M/OL]. 台北:天下文化出版社,1998 [1998-09-26]. http://www.ie.nthu.edu.tw/info/ie.newie.htm(Big5).
[4]  谌颖. 空间交会控制理论与方法研究[D]. 哈尔滨:哈尔滨工业大学,1992:8-13.
[5]  KANAMORI H. Shaking Without Quaking[J]. Science,1998,279(5359):2063-2064.
[6]  CHRISTINE M. Plant Physiology: Plant Biology in the Genome Era[J/OL]. Science,1998,281:331-332[1998-09-23]. http://www.sciencemag.org/cgi/ collection/anatmorp.


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

写过一篇

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表