摘要是论文内容的高度概括,应具有独立性和自含性,即不阅读论文的全文,就能获得必要的信息。摘要应包括本论文的目的、主要内容、方法、成果及其理论与实际意义。摘要中不宜使用公式、结构式、图表和非公知公用的符号与术语,不标注引用文献编号,同时避免将摘要写成目录式的内容介绍。
关键词:进程演变,操作系统调度,硬件协作。
本文将以C语言程序设计课程中的经典案例——hello.c程序为例,深入剖析其从源代码到可执行程序的完整转变过程,并详细探讨它在计算机系统中以进程形态运行的全貌。首先,我们将追踪hello.c源程序如何通过预处理、编译、汇编及链接等一系列复杂步骤,最终蜕变为可执行的二进制目标程序。在这一系列过程中,源代码被逐步转化为机器能够理解和执行的指令。接着,我们将聚焦于程序运行阶段,深入探讨计算机系统的各大硬件组件,如处理器、输入输出设备以及主存储器等,如何与hello程序紧密协作,共同完成任务。同时,我们还将揭示操作系统在进程调度与管理方面的关键作用,展示hello程序如何从静态的代码转变为动态执行的进程。通过这一详尽的案例分析,本文旨在为读者提供一个关于计算机系统如何运行程序的全面而深入的理解,从而加深对计算机科学与技术的认识。
(摘要0分,缺失-1分,根据内容精彩称都酌情加分0-1分)
目 录
2.2在Ubuntu下预处理的命令.......................................................................... - 5 -
3.2 在Ubuntu下编译的命令............................................................................. - 6 -
4.2 在Ubuntu下汇编的命令............................................................................. - 7 -
5.2 在Ubuntu下链接的命令............................................................................. - 8 -
5.3 可执行目标文件hello的格式.................................................................... - 8 -
6.2 简述壳Shell-bash的作用与处理流程..................................................... - 10 -
6.3 Hello的fork进程创建过程..................................................................... - 10 -
6.6 hello的异常与信号处理............................................................................ - 10 -
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 -
8.1 Linux的IO设备管理方法.......................................................................... - 13 -
8.2 简述Unix IO接口及其函数....................................................................... - 13 -
第1章 概述
1.1 Hello简介
1.1.1 P2P
当运行hello.c程序时,整个流程由编译器驱动程序自动管理。首先,驱动程序会启动并读取hello.c源文件。接着,它会执行预处理阶段,这一步骤会对源代码进行初步处理,如包含头文件、宏替换等,最终生成一个预处理后的文件,通常命名为hello.i。
随后,编译器会对预处理后的hello.i文件进行编译。在编译阶段,编译器会将C语言代码转换为汇编语言代码,生成一个汇编语言程序文件,通常命名为hello.s。这个文件包含了程序所需的汇编指令。
接下来,汇编器会接手编译器的输出,即hello.s文件,进行汇编操作。汇编器将汇编语言指令转换为机器语言指令,这些指令是计算机可以直接执行的。汇编完成后,会生成一个包含机器语言指令的“可重定位目标程序”,通常保存为二进制文件,命名为hello.o。
最后,链接器会介入,将各个可重定位目标程序以及必要的库文件链接在一起,生成一个可执行目标文件,即hello。这个可执行文件包含了程序运行所需的所有指令和数据,并且可以被操作系统直接加载和执行。
在生成了可执行文件hello之后,用户就可以在计算机的命令行(Bash或其他shell)中运行这个程序了。操作系统会创建一个新的进程(通过fork操作),并将可执行文件hello加载到这个新进程中。
1.1.2 020
从零到一:程序从开始编写到执行预处理编译汇编链接形成可执行文件并且加载到进程中。
从一到零:程序完成运行或者收到信号后终止,其进程被回收,释放占用的资源,回到未运行前的零。
1.2 环境与工具
1.2.1 硬件环境:
1.2.2 软件环境:
Windows11 64位; Vmware 14; Ubuntu20.04
1.3 中间结果
1.原始代码hello.c。
2.预处理后的代码hello.i。
3.编译后的汇编语言代码hello.s。
4.可重定位目标文件hello.o。
5.hello.o的objdump结果hello_o_disasm.txt。
6.可执行文件hello。
7.hello的objdump结果hello_disasm.txt。
1.4 本章小结
了解了P2P与020,对hello程序有了整体认知。同时为接下来的工作做了准备。
(第1章0.5分)
第2章 预处理
2.1 预处理的概念与作用
程序预处理是指在编译过程中对源代码进行的一系列处理操作,这些操作发生在源代码被编译为目标代码之前。预处理主要由预处理器(preprocessor)负责,它根据预处理指令(preprocessing directive)来处理源代码。
预处理的作用主要包括了宏定义,文件包含(使用#define指令),条件包含(使用#include指令),条件编译(使用#if、#ifdef、#ifndef、#else、#elif和#endif等指令),预定义宏,检测错误等作用。
2.2在Ubuntu下预处理的命令
Gcc -E hello.c 结果保存至 hello.i
2.3 Hello的预处理结果解析
首先是hello.c所涉及的所有头文件的信息。
然后是这些头文件用typedef定义的不同类型的别名
(有省略)然后是include的头文件的主体内容,均完全经过预处理器展开。
最后是helloc的内容。
2.4 本章小结
在本章节中通过执行预处理与查看预处理文件,更加细致了解了预处理的过程,预处理主要扩充了很多被include来的东西,但是实际上大部分内容都是对程序本身没有任何用处的声明,程序只用到了其中声明的一小部分函数。
(第2章0.5分)
第3章 编译
3.1 编译的概念与作用
编译是一个将源代码(source code)转换成目标代码(object code 或 machine code)的过程,这个过程由编译器(compiler)来完成。编译器读取源代码,检查其中的语法错误和可能的逻辑错误,然后生成机器可以直接执行的目标代码。
其主要作用包括:提高执行效率,进行静态类型检查(避免类型错误),错误检查(检查源代码语法错误),实现软件跨平台性,生成优化后代码,生成库与可执行文件。
3.2 在Ubuntu下编译的命令
3.3 Hello的编译结果解析
3.3.1 常量存储
hello程序在调用printf的时候使用了两个常量字符串,它们存在hello程序的只读数据节。
具体如下:
3.3.2变量存储
在hello程序中,只涉及到了局部变量。
在main函数中局部变量共有三个,均通过rbp指针进行访问,分别为传递的参数argc(rbp-20)和argv(rbp-32),以及局部变量i(rbp-4)。
3.3.3循环分析
该程序中有一个for循环,条件为I < 10。
在该循环中,先将i赋值为0,每次循环开始先执行底部L3指令,比较i与9,若I <= 9则跳转回开头重新执行循环,否则结束。
在每次比较跳转前,将i变量加1。
3.3.4 条件判断
除了循环涉及到的条件判断之外,还涉及了arge != 5 的条件判断,具体为将argc与立即数5进行比较,根据条件寄存器操作,若相等则跳转到L2。
3.3.5赋值语句
比如对于循环变量i的赋值,将立即数0移入栈中i的位置
再比如将寄存器中传递参数的值移到栈上,保存argc与argv的值
3.3.6数据运算
比如对i循环变量的更新累计,I = I + 1。将1与栈中数据相加重新存进栈中。
3.3.7函数操作(函数调用与函数返回)
调用了头文件提供的printf sleep等函数
Ret指令标志了函数返回,函数进行清理栈帧等工作。
3.4 本章小结
本章节实现了hello.i至hello.s的编译过程,汇编代码的形成代表着程序的机器级表示的大体成型。
(第3章2分)
第4章 汇编
4.1 汇编的概念与作用
程序汇编(Assembly Programming)涉及到将汇编语言编写的程序转换为机器语言(也称为目标代码或机器码),以供计算机直接执行。汇编语言是一种低级编程语言,它提供了对计算机硬件的直接访问,允许程序员执行如内存管理、端口I/O等底层任务。
程序汇编的主要作用包括了性能优化(实现直接对硬件的访问),底层控制(可以直接操作计算机的硬件)
4.2 在Ubuntu下汇编的命令
gcc -c hello,s 输出至hello.o
4.3 可重定位目标elf格式
ELF文件的主要内容如下:
4.3.1文件头:
ELF的文件头内含有的主要内容包括ELF标识,目标体系结构,节表偏移,程序头表偏移。
4.3.2节头表
(部分省略)由节头表可以获知heello.o一共有13个节,其中有ELF文件中各个节的信息,包括节的名称、类型、偏移、大小等。
4.3.3重定位节
重定位节.rela,text包含八个条目,他们定义了八个符号的重定位信息。举例:第一条是rodata的重定位信息,偏移-4,寻址方式PC32,相对于函数基址偏移0018。
重定位节.rela.eh_frame记录了需要进行地址重定位的异常处理框架(exception handling frame)信息。
4.3.4 符号表
符号表上记录着所有变量,节,函数的属性。其将在语义分析阶段成为目标代码生成阶段地址分配的依据。
4.4 Hello.o的结果解析
观察这个反汇编的结果,我们不难发现它与之前详细分析过的hello.s汇编文件内容高度相似。然而,这次在左侧,我们能看到与汇编指令一一对应的字节形式机器码。每一条汇编指令都精确地映射到特定长度的字节序列上,这些字节序列构成了机器码。其中,机器码的起始部分字节通常标识了该机器指令的类型,而随后的字节则包含了该指令所需的操作数数据。
不过在反汇编结果中,有几处指令的操作数显示为0。实际上这些操作数应该是指向数据节或代码节中的某个地址。当前看到的是可重定位目标文件,其中的地址并非最终执行时所用的真实地址。在链接过程之前,这些地址尚未确定,因此它们暂时被设置为0。
在可重定位目标文件中,这些看似为0的操作数位置实际上是占位符,它们对应于一个重定位条目。这些条目记录了当链接器处理目标文件时,需要如何修改这些地址。链接器将负责在链接阶段,根据各个目标文件中的符号定义和引用,更新这些操作数,赋予它们正确的地址值。
4.5 本章小结
本章将.s文件通过汇编过程得到.o文件,查看了elf文件的具体内容,了解了其中各个部分的作用,又将.o文件反汇编与汇编程序对比,展现了其差异。
(第4章1分)
第5章 链接
5.1 链接的概念与作用
程序链接是将各种代码和数据片段收集并组合成一个单一文件的过程,这个文件可以被加载到内存中并执行。链接可以发生在编译时,由链接器自动执行,将编译完成的目标模块以及它们所需的库函数装配成一个完整的模块。链接的主要目的是解决在编译过程中产生的未解决的问题,如函数或变量的引用等。
程序链接的主要作用包括解决引用问题,地址和空间分配,进行符号解析与重定位,进行共享与动态链接等
5.2 在Ubuntu下链接的命令
ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/9/crtbegin.o hello.o -lc /usr/lib/gcc/x86_64-linux-gnu/9/crtend.o /usr/lib/x86_64-linux-gnu/crtn.o -z relro -o hello
5.3 可执行目标文件hello的格式
5.3.1 ELF头信息
5.3.2 节头(部分省略)
5.3.3程序头(部分省略)
5.4 hello的虚拟地址空间
图中第一行和第二行的段是hello可执行文件的信息,其对应的是5.3中程序头提到的四个type为load的段,第三行和第四行根据name,是来自ld227.so的动态链接库,剩下则是程序栈以及内核段落的位置。
5.5 链接的重定位过程分析
第一,main函数的每条指令所在的地址以及被确认,因为所有模块的节都已经被组合起来,虚拟地址空间已经确定。而之前都是相对于0的地址,因为那时main还只是一个单独模块,只能给出相对于0的地址偏移。
第二,可以观察到的是,之前在hello.o用占位符0替代的地址现在已经全部补全
打个比方,0015的数据之前是使用了00对操作数地址占位,以及在旁备注了一条重定位条目。在链接时,链接器先是为每个段分配了基址。从而可以使用重定位条目计算出操作数的具体地址
5.6 hello的执行流程
1.程序启动(_start):
程序启动的起点是_start符号。当操作系统将hello加载到内存中并准备执行时,其跳转到这个特定的内存位置。_start是编译器和链接器共同为程序自动设置的入口点。在此阶段,程序会执行一系列基本的初始化操作,比如初始化堆栈和调用_libc_start_main函数,为后续的程序执行做好准备。
2.C运行时库初始化(_libc_start_main)
_libc_start_main函数是C运行时库提供的关键部分。在调用main函数之前,会负责执行一系列重要的初始化任务。包括设置全局变量的初始值、调用特定的初始化函数(比如__libc_csu_init)以及注册程序终止时需要调用的函数(通过__GI___cxa_atexit)。这些初始化步骤确保了程序在执行main函数之前能够在一个稳定且符合预期的环境中运行。
3.调用主函数(main):
程序转移到main函数入口点,执行用户在main函数中定义的内容。
4.调用库函数(如printf):
在程序执行过程中,调用了一系列库函数来执行相关功能,比如sleep函数与printf函数
5.程序终止与清理工作:
当main函数执行完毕并返回时,C运行时库会负责执行一系列的清理工作。这些工作包括调用在_libc_start_main函数中注册的退出函数、释放程序在运行过程中分配的资源等。完成这些清理工作后,控制权会返回到操作系统,程序终止执行。
5.7 Hello的动态链接分析
Hello程序在执行时可能对动态链接库内的函数进行调用,这些函数的地址在PLT表和GOT表中标识。
当前还未运行程序,所以暂无数据,在运行程序时,_dl_start和_sl_init可以修改PLT和GOT,即为加载动态链接库的符号。
运行_sl_init前
运行后
可以看到601000处数据发生了变化
5.8 本章小结
本章实现了链接,从.o文件生成可执行文件,通过实践更深地理解了链接过程中的重定位以及对于动态库的调用的具体问题
(第5章1分)
第6章 hello进程管理
6.1 进程的概念与作用
进程是操作系统分配资源的基本单位,也是系统进行并发控制和资源分配的一个独立单位。简单来说,进程就是一个正在执行的程序的实例。
进程的作用包括了方便计算机进行资源分配,进程并发执行提高效率等。
6.2 简述壳Shell-bash的作用与处理流程
Shell-bash充当了用户与操作系统内核之间的接口。Shell的主要作用是接收用户输入的命令,并将这些命令解释(或翻译)成内核能够理解的语言,然后交由内核执行。这样,用户就可以通过Shell来间接地控制和管理系统的各种资源
其处理流程包括了读取输入,解析输入,查找对应程序并交予内核执行,输出返回的运行结果。
6.3 Hello的fork进程创建过程
首先,SHELL调用fork()。创建一个新的进程,新进程拥有与hello一样的虚拟地址,具有相同的上下文(复制得到),就是说他们共享相同的代码与数据字段,但是拥有自己独立的堆和栈,并且子进程与父进程PID不同。另外,在子进程中,fork返回0,在父进程中则返回子进程的PID值。Hello子进程与父进程并行,在子进程结束后可以等待父进程中函数进行回收。
6.4 Hello的execve过程
Execeve函数接受filename(hello的路径与名称),argv和envp参数,调用execve后,原程序将不再执行,而是完全由新程序hello接管,Execve将会覆盖当前进程的代码段,数据段,堆栈段,并且用hello的内容覆盖他们。Hello的代码数据堆栈将会映射在虚拟空间中。Execve函数成功执行后将不会返回信息。
6.5 Hello的进程执行
假设hello程序正在正常运行,此时,hello程序具有完整的上下文信息,包括了其代码,数据,堆栈,寄存器以及其他占用的资源,这些信息在hello运行过程中不能被破坏。
此时,hello在执行完sleep函数的syscall指令后,由自己引发了一个陷阱,那么立刻保存下条指令地址并且由用户态转到内核态执行异常处理程序,该程序保存hello的上下文,并且将hello设置为休眠状态,为hello设置时钟,并且加载进程B的上下文开始运行进程B,即操作系统为进程B分配了时间片,使得进程B可以连续执行一段时间。当hello结束休眠时,进程B接收到信号,系统再次转入内核态并且将控制流转交给hello。
6.6 hello的异常与信号处理
回车:
回车后显示屏上出现空行,hello继续执行。先发生异常执行了回车进程之后,重新转回执行hello进程
CTRL + Z:
中断指令,程序接受中断信号(SIGSTP)暂停。
PS:
打印出当前进程状态。
JOBS:
可以查看到停止中的作业
PSTREE(省略部分):
使用树状图显示出所有运行中程序
FG以及KILL:
重新开始执行程序以及杀死程序。
CTRL + C:
将正在运行中的程序终止(SIGINT)。
6.7本章小结
通过本章节,更加深刻理解了hello进程的创建执行,中断回收等过程
(第6章1分)
第7章 hello的存储管理
7.1 hello的存储器地址空间
逻辑地址是指在计算机体系结构中,从应用程序角度看到的内存单元、存储单元或网络主机的地址,即程序员在编写中使用的各个存储单元的地址,表示为“段:偏移地址”的形式。
线性地址是逻辑地址到物理地址变换之间的中间层。
虚拟地址是虚拟内存空间内的地址,他使得每个进程都有自己的连续地址空间,当hello程序运行时,操作系统为其分配一个虚拟地址空间。
物理地址是实际的内存地址,hello的虚拟地址通过页表映射到物理地址,从而对内存单元进行访问。
7.2 Intel逻辑地址到线性地址的变换-段式管理
逻辑地址转换为线性地址的过程主要包括:
1.使用段选择符中的偏移值(段索引)在GDT或LDT表中定位相应的段描述符
2.利用段选择符检验段的访问权限和范围,以确保该段可访问。
3.把段描述符中取到的段基地址加到偏移量上,最后形成一个线性地址。
7.3 Hello的线性地址到物理地址的变换-页式管理
进行线性地址到物理地址的变换过程主要包括:
Hello的某一条线性地址可以分为页目录索引,页表索引和页内偏移。先使用页目录索引查找相应页表,然后使用页表索引查找页表项目,取出其中存放的物理页地址,再与页内偏移组合形成物理地址。
7.4 TLB与四级页表支持下的VA到PA的变换
首先hello发出一条VA,这条VA中的VPN被送往TLB,假如TLB命中,将直接取出PTE形成PA。假如没有命中,对主存发送PTEA,PTEA中,VPN包括了VPN1234四部分,分别用于访问四级页表,之后取出对应的PTE,更新TLB,并且形成对应的PA。
7.5 三级Cache支持下的物理内存访问
三级cache支持下,物理内存首先访问第一级cache,如果命中,将直接从第一级cache下取出数据,这时的速度非常快。假如不命中,需要继续访问第二级cache,如果命中,这一数据需要被写入第一级cache,同时由处理器决定要舍弃cache中的哪一块数据。被替换的数据需要回写到内存中,当再次需要这些数据时重新加载。对于二三级caache的访问,以及三级cache与主存之间的访问也是同理。他们的速度是逐渐减慢的。
7.6 hello进程fork时的内存映射
当fork被hello调用时,生成子进程会继承父进程的内存映射,包括文件映射和匿名映射,遵循写时复制的规则,即虽然子进程获得了父进程虚拟地址空间的副本,但实际上物理内存中的页面并没有立即被复制。只有当某个页面被修改时(即写入操作),该页面才会被复制,并且复制后的页面是私有的,不再与父进程共享。
7.7 hello进程execve时的内存映射
Hello进程执行execve时,他的所有内存映射,包括代码数据段,堆栈,环境变量表等,都会被由execve引发的新程序的内存映射所替代。运行成功后,execve函数不返回,控制流由hello程序交给新的运行中的B程序。
7.8 缺页故障与缺页中断处理
当hello所要访问的页面不在物理内存时,就会发生缺页故障,系统保存hello的上下文并且转入内核状态执行缺页异常处理程序。缺页处理程序确认出物理内存中的牺牲页,调入新的页面,更新页表,然后返回原来的hello程序,重新执行hello程序中导致了缺页异常的指令。
7.9动态存储分配管理
动态内存管理是指程序在运行中通过malloc等函数进行的内存请求与内存释放。
malloc 是一个在 C 和 C++(通过 C 兼容性)中常用的函数,用于在堆(heap)上动态分配内存。它的名字来源于“memory allocation”的缩写。参数为要分配的字节数size,如果执行成功,则返回一个指向已分配内存块的指针,若分配失败则返回NULL。
内存管理的策略则例如隐式空间链表和显式空间链表,其中,隐式空间链表带边界标签的隐式空闲链表使用边界标签(boundary tags)来管理内存块,内存块之间没有显式的指针链接,显式空间链表使用链表来串联所有空闲的块。
7.10本章小结
本章涉及了不同种类的地址以及fork,execve函数,内存分配函数等,进一步加深了对hello运行的理解。
(第7章 2分)
第8章 hello的IO管理
8.1 Linux的IO设备管理方法
Linux的设备管理的主要任务是控制设备完成输入输出操作,所以又称输入输出(I/O)子系统。它的任务是把各种设备硬件的复杂物理特性的细节屏蔽起来,提供一个对各种不同设备使用统一方式进行操作的接口。Linux把设备看作是特殊的文件,系统通过处理文件的接口—虚拟文件系统VFS来管理和控制各种设备。
8.2 简述Unix IO接口及其函数
Unix IO接口及其函数是Unix和类Unix系统中进行输入输出操作的重要组成部分。这些接口和函数允许程序与系统中的各种IO设备(如网络、磁盘和终端等)进行交互,实现数据的读取和写入。Unix IO接口的主要特点是文件到设备的优雅映射,这使得内核可以导出一个简单的接口,称为Unix I/O。在Unix中,几乎所有的输入和输出都被统一处理,无论是文件、网络还是其他设备,都被模型化为文件,这种设计简化了IO操作的处理方式。
Unix IO接口提供了一些基本的系统调用(syscall),用于执行IO操作。这些系统调用,主要包括:
open:此函数用于打开文件或设备,并返回一个非负整数,即文件描述符。后续的所有操作都基于这个文件描述符进行。open函数的参数包括文件路径和访问模式等。
read:此函数用于从已打开的文件或设备中读取数据。它接受文件描述符、缓冲区地址和大小作为参数,并返回实际读取的字节数。
write:此函数用于向已打开的文件或设备写入数据。它接受文件描述符、数据缓冲区和大小作为参数,并返回实际写入的字节数。
close:此函数用于关闭已打开的文件或设备。它接受文件描述符作为参数,并在成功关闭文件时返回。
8.3 printf的实现分析
printf函数的执行流程包括两个主要步骤:首先,它会解析输入的格式化字符串,并根据所给的参数生成需要显示的完整信息;随后,通过系统调用write,引发故障,将这些信息发送到标准输出设备。在操作系统的内核层面,接收到的数据会进一步被传递到字符显示驱动程序。这个驱动程序负责将字符数据转换为屏幕上对应的像素表示,这些像素数据随后被存在储VRAM中。最终,显示芯片会依据设定的刷新频率,逐行从VRAM中读取像素数据,并通过信号线将每一个像素点传输到液晶显示器上,从而呈现出我们所能看到的图像。
8.4 getchar的实现分析
Getchar函数当识别到来自键盘的输入的字符后,将会引发中断,进入异常处理程序,接受按键扫描码转成ascii码,保存到系统的键盘缓冲区。getchar等调用read系统函数,通过系统调用读取按键ascii码,直到接受到回车键才返回。或者在接受到特定的设置字符后将缓冲区的字符返回给程序。
8.5本章小结
本章分析了printf和getchar函数的实现,了解了IO设备管理以及UNIX I/O函数,加深了unix系统的认识。
(第8章1分)
结论
通过本次大作业的深入实践,我深入领略了计算机系统底层操作的复杂与精妙。从源代码的编写到最终可执行文件的生成,每一个步骤都蕴含了无数细节与挑战,为我提供了宝贵的学习与成长的机会。在此过程中,我更加深刻地认识到进程管理、存储管理和IO管理作为计算机系统三大核心组成部分的重要性。它们的设计和实现不仅直接影响着程序的运行效率,更关乎整个系统的稳定与可靠。
展望未来,我怀揣着对计算机系统探索的无限热情,将继续深入学习并研究这些领域的最新技术和趋势。我渴望不断提升自己的技术能力,并培养创新能力,以应对日益复杂的计算机系统和不断变化的业务需求。同时,我也期望能将本次大作业中所学到的知识和技能应用于实际项目中,为解决现实世界中的复杂问题贡献自己的一份力量。
(结论0分,缺失 -1分,根据内容酌情加分)
附件
列出所有的中间产物的文件名,并予以说明起作用。
(附件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分)