计算机系统大作业

计算机系统

大作业

题 目 程序人生-Hello’s P2P
专 业 计算学部
学   号 120L020502
班   级 2003011
学 生 龚泽豪    
指 导 教 师 郑贵滨

计算机科学与技术学院
2021年5月
摘 要
本文详细介绍了hello.c是如何在计算机上运行的,经过预处理,编译,汇编,链接生成可执行文件,最后在shell中使用命令来创建或管理进程、内存管理、I/O管理

关键词:hello周期、I/O、进程、内存

(摘要0分,缺失-1分,根据内容精彩称都酌情加分0-1分)

目 录

第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简介
Hello.c程序经过cpp的预处理,ccl的编译、as的汇编、ld的链接最终成为可执行目标文件hello。在shell中输入启动命令,shell将其fork成进程来运行。
Shell为进程进行execve,进入程序入口后程序开始载入物理内存。
执行目标代码,cpu为hello分配时间片执行逻辑控制流。
程序运行结束时,shell父进程回收hello进程,内核删除为其产生的数据结构。
1.2 环境与工具
硬件环境:九代i7;16gram;x86-64架构
软件环境:windows10;ubuntu 20.04;vmware
开发与调试工具:gcc;gdb;as;ld;edb;readelf;vscode
1.3 中间结果
hello.i:经过预处理后的文件
hello.s:编译后生成的汇编文件
hello.o:汇编后生成的可重定位文件
hello.asm:反汇编得到的文件
hello: 链接后生成的可执行目标文件
1.4 本章小结
本章对hello进行了简单的介绍,分析了其P2P和020的过程,列出了本次任务的环境和工具,并且阐明了任务过程中出现的中间产物及其作用。
(第1章0.5分)

第2章 预处理
2.1 预处理的概念与作用
概念:在编译之前进行的处理。 C语言的预处理主要有三个方面的内容: 1.宏定义; 2.文件包含; 3.条件编译。 预处理命令以符号“#”开头。

作用:
删除注释。
用实际值代替用#define定义的字符串。
将源文件中用#include形式声明的文件复制到新的程序中。
条件编译,根据#if后面的条件决定要进行编译的代码。

2.2在Ubuntu下预处理的命令

gcc -E hello.c -o hello.i

图表 1

2.3 Hello的预处理结果解析

图表 2
2.4 本章小结

通过本章了解了c语言在编译前的预处理过程,明白了预处理的概念及作用,学会了GCC下预处理对应的指令,对预处理的结果有了一定的了解,更好的了解了预处理的过程。

(第2章0.5分)

第3章 编译
3.1 编译的概念与作用

概念:编译器将文本文件hello.i翻译成文本文件hello.s,它包含一个汇编语言程序。它是以高级程序设计语言书写的源程序作为输入,以汇编语言或者机器语言表示的目标程序作为输出。

作用:可以在转化时对程序的实现进行优化。

3.2 在Ubuntu下编译的命令
gcc -S hello.i -o hello.s

图表 3
3.3 Hello的编译结果解析

图表 4

图表 5
3.3.1汇编指令介绍
file:声明源文件
.text:代码节
.section: 是在程序中"逻辑地"规划一段区域,此区域便是节。
.rodata:只读代码段
.align:数据或者指令的地址对其方式
.string:声明一个字符串(.LC0,.LC1)
.global:声明全局变量(main)
.type:声明一个符号是数据类型还是函数类型
3.3.2数据
1、字符串

2、argc

3、argv

图表 6
4、局部变量

图表 7
3.3.3指令操作
Movl:赋值操作
Leap:赋值操作
Sub:减法指令
Call:无条件跳转指令
Je:条件跳转,相等时跳转
Cmpl:比较操作
3.4 本章小结
学习了指令操作,对编译过程有了一定的了解。
(第3章2分)

第4章 汇编
4.1 汇编的概念与作用
概念:汇编的概念是指的将汇编语言程序翻译成机器指令,并将这些指令打包成一种叫做可重定位目标程序,并将这个结果保留.o目标文件中。
作用:
1,实现了文本文件到二进制文件的转化。
2,将汇编指令转换成一条条机器可以直接读取分析的机器指令。

4.2 在Ubuntu下汇编的命令
gcc -c hello.s -o hello.o

图表 8
4.3 可重定位目标elf格式
查看ELF头:readelf -h hello.o

图表 9
它包含了Magic、文件类型、 系统架构、目标文件的类型、目标文件的信息、数据、系统架构、程序头起点、表头大小等信息。

查看节部头表: readelf -S hello.o

图表 10

图表 11
一共有13个节,包含了文件中出现的各个节的语义,包括节的类型、位置和大小等信息。

查看符号表: readelf -s hello.o

图表 12
符号表中记录了这个模块定义的可以提供给其他模块引用的全局符号。

查询重定位条目: readelf -r hello.o

图表 13
重定位是一种用符号定义连接符号引用的过程。可重定位文件必须拥有描述如何去修改它们section contents的信息,好让可执行或共享目标文件保存程序镜像的正确信息。可重定位条目就是这些数据。
4.4 Hello.o的结果解析
objdump -d -r hello.o

图表 14

图表 15
机器语言与汇编语言的映射关系:每一条汇编语言操作码都可以用机器二进制数据来表示,进而可以将所有的汇编语言(操作码和操作数)和二进制机器语言建立一一映射的关系。
分支转移: 在汇编语言中,分支转移命令是由助记符来标识,通过用符号.L2等助记符,跳转到相应的位置。而在机器语言反汇编程序中,分支转移命令是直接跳转入目的地址。
函数调用:在汇编语言中,函数调用之后直接跟着函数名称。而在机器语言的反汇编程序中,call的目标地址是下一条指令的地址。
4.5 本章小结
通过学习hello的反汇编代码,比较hello.o和hello.s的区别,了解了汇编代码和机器码之间的映射关系,对代码的底层逻辑有了更深刻的认识。
(第4章1分)

第5章 链接
5.1 链接的概念与作用
概念:把各个目标文件整合的过程就叫链接过程。整合后的文件就叫可执行程序,windows后缀为.exe,Linux后缀为.out
作用:
1、符号统一 : 直接举个C语言中的例子,假设程序有两个.c文件,分别是a.c和b.c,这两个文件中都有名叫var的变量,a.c被编译得到a.o,b.c被编译得到b.o,将a.o和b.o链接到同一个文件时,var命名重复了,需要根据规则对着两个符号进行统一,与此相似的还有函数名的“符号统一”问题。
2、当程序调用函数库(如标准C库)中的一个函数printf,printf函数存在于一个名为printf.o的单独的预编译好了的目标文件中,而这个函数必须通过链接器(ld)将这个文件合并到hello.o程序中,结果得到hello文件
5.2 在Ubuntu下链接的命令

图表 16

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

图表 17
分析hello的ELF格式,用readelf等列出其各段的基本信息,包括各段的起始地址,大小等信息。

图表 18

图表 19
5.4 hello的虚拟地址空间

图表 20

图表 21
如.text大小为0x145开始地址为0x4010f0

图表 22
如.init大小为0x1b 开始地址为0x401000
5.5 链接的重定位过程分析
objdump -d -r hello

图表 23

图表 24

objdump -d -r hello.o

图表 25
对比:hello比hello.o多了_init 、.plt、printf@plt等文件节
结合分析可得hello重定位的过程:重定位节和符号定义链接器将所有类型相同的节合并在一起后,这个节就作为可执行目标文件的节。然后链接器把运行时的内存地址赋给新的节,赋给输入模块定义的每个节,以及赋给输入模块定义的每个符号,当这一步完成时,程序中每条指令和全局变量都有唯一运行时的地址。
重定位节中的符号引用这一步中,连接器修改代码节和数据节中对每个符号的引用,使他们指向正确的运行时地址。
重定位条目当编译器遇到对最终位置未知的目标引用时,它就会生成一个重定位条目。
5.6 hello的执行流程
d-2.27.so!_dl_start

ld-2.27.so!_dl_init

hello!_start

libc-2.27.so!__libc_start_main

-libc-2.27.so!__cxa_atexit

-libc-2.27.so!__libc_csu_init

hello!_init

libc-2.27.so!_setjmp

libc-2.27.so!exit
5.7 Hello的动态链接分析
对于动态共享链接库中PIC函数,编译器没有办法预测函数的运行时地址,所以需要为其添加重定位记录,并等待动态链接器处理。为避免运行时修改调用模块的代码段,链接器采用延迟绑定的策略。动态链接器使用过程链接表PLT和全局偏移量表GOT实现函数的动态链接。其中GOT 中存放函数目标地址,PLT使用 GOT中地址跳转到目标函数。

图表 26

图表 27

图表 28
在之后的调用函数时,首先跳转到PLT执行.plt中逻辑,第一次访问跳转时GOT地址为下一条指令,将函数序号压栈,然后跳转到PLT[0],在PLT[0]中将重定位表地址压栈,然后访问动态链接器,在动态链接器中使用函数序号和重定位表确定函数运行时地址,重写GOT,再将控制传递给目标函数。
5.8 本章小结
本章介绍了链接的相关内容,熟悉了链接的指令,如何将.o文件转为可执行文件。回忆了edb的使用方法,分析了重定位的相关知识。
(第5章1分)

第6章 hello进程管理
6.1 进程的概念与作用
概念:
进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体。它不只是程序的代码,还包括当前的活动,通过程序计数器的值和处理寄存器的内容来表示。

作用:
进程作为一个执行中程序的实例,系统中每个程序都运行在某个进程的上下文中,上下文是由程序正确运行所需的状态组成的。这个状态包括存放在内存中的程序的代码和数据,它的栈、通用目的寄存器的内容、程序计数器、环境变量以及打开文件描述符的集合
6.2 简述壳Shell-bash的作用与处理流程
作用:作为命令处理器,接受用户输入的命令,然后根据命令进行相关操作,比如调用相关的程序。作为命令语言,它交互式解释和执行用户输入的命令或者自动地解释和执行预先设定好的一连串的命令。作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。
处理流程:
从终端读入用户输入的命令
对命令解析,并判断其是否为内置命令
若是内置命令,则直接执行
若不是,则调用execve函数创建子进程运行
再判断是否为前台运行程序,若是,则调用等待函数,等待前台程序结束。否则程序转入后台,接受用户下一步输入的命令
Shell接受键盘输入的信号,并且应该对信号产生相应的反应
回收僵死进程
6.3 Hello的fork进程创建过程
当在shell中运行hello后,父进程通过调用fork函数创建一个新的运行的子进程。其函数原型为pid_t fork(void);其调用一次返回两次,子进程返回0,父进程返回子进程的ID。作用:shell是命令行界面,是系统内核的一层壳,作用是用来保护内核同时传递入与计算机交互的信息.它只是系统的一个工具,我们可以使用它来操作计算机。

图表 29
6.4 Hello的execve过程
execve函数在当前进程的上下文中加载并运行一个新程序。
execve函数加载并运行可执行文件filename(hello),且带参数列表argv和环境变量envp。只有当出现错误时,例如找不到filename,execve才会返回到调用程序。
6.5 Hello的进程执行

图表 30
上下文信息:上下文就是内核重新启动一个被抢占的进程所需要的状态
进程时间片:一个进程执行它的控制流的一部分的每一时间段叫做时间片。
多任务:多任务也叫做多时间片。
调度:在进程执行的某些时刻,内核可以决定抢占当前进程,并重新开始一个先前被强占的进程。
用户态核心态转换:进程hello初始运行在用户模式中,直到它通过执行系统调用函数sleep或者exit时便陷入到内内核。
6.6 hello的异常与信号处理

hello程序出现的异常可能有:

中断:在hello程序执行的过程中可能会出现外部I/O设备引起的异常。

陷阱:陷阱是有意的异常,是执行一条指令的结果,hello执行sleep函数的时候会出现这个异常。

故障:在执行hello程序的时候,可能会发生缺页故障。

终止:终止时不可恢复的错误,在hello执行过程可能会出现DRAM或者SRAM位损坏的奇偶错误。

可能产生的信号有:SIGINT、SIGKILL、SIGSEGV、SIALARM、SIGCHLD

命令:./hello 120L020502 龚泽豪 5

Ctrl-C:在键盘上输入Ctrl+c会导致内核发送一个SIGINT信号到前台进程组的每个进程,默认情况是终止前台作业。

图表 31
Ctrl-Z内核会发送SIGSTP:

图表 32

ps :

图表 33
jobs :

图表 34
pstree :

图表 35

图表 36
fg :

图表 37
kill:内核会发送SIGKILL信号给我们指定的pid(hello程序),结果是杀死了hello程序。

图表 38
6.7本章小结
通过对hello的创建、加载和终止,使得对hello执行过程中产生信号和信号的处理过程有了更多的认识,加深了对异常的理解。
(第6章1分)

第7章 hello的存储管理
7.1 hello的存储器地址空间

逻辑地址:
是指由程序hello产生的与段相关的偏移地址部分
线性地址:
是逻辑地址到物理地址变换之间的中间层。程序hello的代码会产生逻辑地址,或者说是(即hello程序)段中的偏移地址,它加上相应段的基地址就生成了一个线性地址。
虚拟地址:
虚拟地址也就是线性地址。
物理地址的概念:
存储器中的每一个字节单元都给以一个唯一的存储器地址,用来正确地存放或取得信息
7.2 Intel逻辑地址到线性地址的变换-段式管理
逻辑地址由两部分组成:段标识符,段内偏移量。
段标识符是由一个16位长的字段组成,称为段选择符。其中前13位是一个索引号,剩下3位包含硬件信息。其中索引号可以直接理解成数组下标,它对应的“数组”就是段描述符表,段描述符具体描述了一个段地址,这样,很多段描述符就组成段描述符表。可以通过段标识符的前13位,直接在段描述符表中找到一个具体的段描述符,这个描述符就描述了一个段。
7.3 Hello的线性地址到物理地址的变换-页式管理
页表是一个页表条目(PTE)的数组,将虚拟页地址映射到物理页地址。

线性地址即虚拟地址,用VA来表示。VA被分为虚拟页号(VPN)与虚拟页偏移量(VPO),CPU取出虚拟页号,通过页表基址寄存器(PTBR)来定位页表条目,在有效位为1时,从页表条目中取出信息物理页号(PPN),通过将物理页号与虚拟页偏移量(VPO)结合,得到由物理地址(PPN)和物理页偏移量(PPO)组合的物理地址。

7.4 TLB与四级页表支持下的VA到PA的变换
TLB:翻译后备缓冲器,其中每一行都保存着一个由单个PTE组成的块。通过这种方式我们可以再把VPN分成TLBT(TLB标记)和TLB索引(TLBI),根据索引和标记在TLB中寻找对应的PPN,TLB命中可以减少内存访问,就和之前的cache命中类似,这里少了行,也可以理解成一组只有一行,类似直接映射。
多级页表:将虚拟地址的VPN划分为相等大小的不同的部分,每个部分用于寻找由上一级确定的页表基址对应的页表条目。
7.5 三级Cache支持下的物理内存访问
1,得到了物理地址VA,首先使用物理地址的CI进行组索引(每组8路),对8路的块分别匹配 CT进行标志位匹配。如果匹配成功且块的valid标志位为1,则命中hit。然后根据数据偏移量 CO取出数据并返回。

2,若没找到相匹配的或者标志位为0,则miss。那么cache向下一级cache,这里是二级cache甚至三级cache中寻找查询数据。然后逐级写入cache。

3,在更新cache的时候,需要判断是否有空闲块。若有空闲块(即有效位为0),则写入;若不存在,则进行驱逐一个块(LRU策略)
7.6 hello进程fork时的内存映射
当fork 函数被shell调用时,内核为hello进程创建各种数据结构,并分配给它一个唯一的PID 。子进程的内存数据完全复制父进程。内核创建了hello进程的mm_struct、区域结构和页表的原样副本。它将两个进程中的每个页面都标记为只读,并将两个进程中的每个区域结构都标记为私有的写时复制。当fork 在hello进程中返回时,hello进程现在的虚拟内存刚好和调用fork 时存在的虚拟内存相同。同时,写时复制机制也会在其中一个进程写操作时创建新的页面,由此也就有了私有地址的概念。
当fork 在hello进程中返回时,hello进程现在的虚拟内存刚好和调用fork 时存在的虚拟内存相同。
7.7 hello进程execve时的内存映射
删除已存在的用户区域:删除当前进程虚拟地址的用户部分中已存在的区域结构。
映射私有区域:为新程序的代码、数据、bss和栈区域创建新的区域结构。
映射共享区域hello 程序与共享对象 libc.so 链接,libc.s是动态链 接到这个程序中的,然后再映射到用户虚拟地址空间中的共享区域内。
设置程序计数器:execve做的最后一件事情就是设置当前进程上下文中的程序计数器,指向代码区域的入口点。
7.8 缺页故障与缺页中断处理
发生缺页故障时,处出发缺页异常处理程序,缺页处理程序确认出物理内存中的牺牲页,如果这个页已经被修改了,则把它换到磁盘。缺页处理程序调入新的页面,并更新内存中的PTE,缺页处理程序返回到原来的进程,再次执行导致缺页的命令。CPU将引起缺页的虚拟地址重新发送给MMU。因为虚拟页面已经缓存在物理内存中,所以就会命中。
7.9动态存储分配管理
隐式空闲链表:
在隐式空闲链表中,因为空闲块是通过头部中的大小字段隐含地连接着的。分配器可以通过遍历堆中所有的块,从而间接地遍历整个空闲块的集合。其中,一个设置了已分配的位而大小为零的终止头部将作为特殊标记的结束块。
显式空闲链表:
显式空闲链表是将空闲块组织为某种形式的显式数据结构。因为根据定义,程序不需要一个空闲块的主体,所以实现这个数据结构的指针可以存放在这些空闲块的主体里面。如,堆可以组织成一个双向链表,在每个空闲块中,都包含一个前驱与一个后继指针。
分离的空闲链表:
维护多个空闲链表,每个链表中的块有大致相等的大小。将所有可能的块大小分成一些等价类,也叫做大小类。
7.10本章小结
通过对段式和页式存储,页表的存储管理,虚拟地址物理地址的转换,进程的加载时的内存映射,缺页故障和处理,动态内存分配等一系列关于进程存储问题的讨论,对程序运行时OS对内存的相关管理机制以及进程运行的实现有了一定的理解。
(第7章 2分)

第8章 hello的IO管理
8.1 Linux的IO设备管理方法

设备的模型化:文件
设备管理:unix io接口
所有的I/O设备都被模型化为文件,而文件就是一个字节序列。所有的输入和输出都被当做对相应文件的读和写来执行。
8.2 简述Unix IO接口及其函数
接口:
将设备映射为文件的方式,允许Unix内核引出一个简单、低级的应用接口。
函数:
5个函数:open(打开)、close(关闭)、read(读)、write(写)、lseek(定位)
打开文件 :返回一个小的非负整数,即描述符。用描述符来标识文件。每个进程都有三个打开的文件:标准输入(0)、标准输出(1)、标准错误(2)

改变当前文件位置 : 从文件开头起始的字节偏移量。系统内核保持一个文件位置k,对于每个打开的文件,起始值为0。应用程序执行seek,设置当前位置k,通过调用lseek函数,显示地修改当前文件位置。

读写文件。读操作:从文件拷贝n个字节到存储器,从当前文件位置k开始,将k增加到k+n,对于一个大小为m字节的文件,当k>=m时,读操作触发一个EOF的条件。写操作:从存储器拷贝n个字节到文件,k更新为k+n
read函数:从描述符为fd的当前文件位置拷贝至多n个字节到存储器位置buf。返回-1表示一个错误,返回0表示EOF,否则返回实际读取的字节数。
write函数:从存储器位置buf拷贝至多n个字节到描述符fd的当前文件位置。

关闭文件:内核释放文件打开时创建的数据结构,并恢复描述符到描述符池中,进程通过调用close函数关闭一个打开的文件。关闭一个已关闭的描述符会出错。
8.3 printf的实现分析
https://www.cnblogs.com/pianist/p/3315801.html

图表 39
vsprintf的作用就是格式化。它接受确定输出格式的格式字符串fmt。用格式字符串对个数变化的参数进行格式化,产生格式化输出。

图表 40
在printf中调用系统函数write(buf,i)将长度为i的buf输出,在write函数中,将栈中参数放入寄存器,ecx是字符个数,ebx存放第一个字符地址,

图表 41
syscall将字符串中的字节从寄存器中通过总线复制到显卡的显存中,显存中存储的是字符的ASCII码。
8.4 getchar的实现分析
用户输入命令后,getchar从stdio流中每次读入一个字符。getchar函数的返回值是用户输入的第一个字符的ASCII码,如出错返回-1,且将用户输入的字符回显到屏幕。如用户在按回车之前输入了不止一个字符,其他字符会保留在键盘缓存区中,等待后续getchar调用读取。

异步异常-键盘中断的处理:键盘中断处理子程序。接受按键扫描码转成ascii码,保存到系统的键盘缓冲区。

getchar等调用read系统函数,通过系统调用读取按键ascii码,直到接受到回车键才返回。

8.5本章小结
本章了解了Linux下IO设备的管理方法,IO接口及其函数,对于printf和getchar函数有了更深刻的理解。
(第8章1分)
结论

过程:
预处理:hello.c预处理到hello.i文本文件;
编译:hello.i编译到hello.s汇编文件;
汇编:hello.s汇编到二进制可重定位目标文件hello.o;
链接:hello.o链接生成可执行文件hello;
运行hello程序
判断是否为内置命令,如果是则执行,不是则创建一个子进程
在子程序运行execve程序
访问内存:hello的运行需要地址
调用系统函数如printf,与linux I/O息息相关
结束运行:hello最终被shell父进程回收,内核会收回为其创建的所有信息
通过对计算机系统的学习,使我感到计算机每一个部分的逻辑都非常紧密,一环扣一环,许多设计非常精巧,并且能和实际相对应然后巧妙的实现。学习了这门课,使我对计算机系统有了更深入的理解,对以后的编程也有了很大的帮助。
(结论0分,缺失 -1分,根据内容酌情加分)

附件
hello.c:源程序文件
hello.i:预处理后的文本文件
hello.s:编译后汇编程序文本文件
hello.o:汇编后的可重定位目标程序(二进制文件)
hello.out: hello反汇编之后的可重定位文件
hello:链接后的可执行目标文件

(附件0分,缺失 -1分)

参考文献
为完成本次大作业你翻阅的书籍与网站等
[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.
(参考文献0分,缺失 -1分)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值