计算机系统

计算机系统大作业

题 目 程序人生-Hello’s P2P

摘 要
本文通过hello程序的P2P(From Program to Process),从预处理,编译,汇编。链接等阶段分析程序从C文件变为可执行文件的过程,得到每一步文件的生成原理以及具体的操作步骤。
关键词:程序执行,从程序到进程,汇编,存储
目 录

第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简介

  1. P2P过程:即From program to process,从程序到进程。hello.c程序编写后,cpp预处理预编译指令,ccl编译将C语言翻译成汇编语言,as汇编将汇编语言翻译成机器语言,ld链接将目标文件外加库连接为一个可执行文件。
  2. 020过程:
    shell首先为其fork子进程,execve加载并执行hello,映射虚拟内存,进入程序入口后将程序载入物理内存,进入main函数执行目标代码,CPU为运行的hello分配时间片执行逻辑控制流。当程序运行结束后,shell父进程负责回收hello进程,内核删除相关数据结构。即“从0开始,以0结束。
    1.2 环境与工具
    1.2.1 硬件环境
    i7-8550UCPU,1.80GHz,8GRAM,
    1.2.2 软件环境
    Windows10 64位,Vmware15 Pro15.5.0 build-14665864,Ubuntu18.04
    1.2.3 开发工具
    VisualStudio2019,Codeblocks,gcc,gdb,edb,readelf
    1.3 中间结果
    列出你为编写本论文,生成的中间结果文件的名字,文件的作用等。
    文件名称 文件说明
    hello.c hello源文件
    hello.i 预处理后文本文件
    hello.s 编译得到的汇编文件
    hello.o 汇编后的可重定位目标文件
    hello 链接后的可执行文件
    hello.objdump1 hello可执行文件反汇编代码
    hello.elf hello的elf文件
    hello.objdump hello.o(链接前)的反汇编文件
    hello_o_elf.txt hello.o的ELF格式
    1.4 本章小结
    本章对hello进行简单介绍,叙述其P2P和020的过程,说明了所需要的硬件、软件环境和调试工具,并且列举了所有的中间结果文件及其目的。

第2章 预处理
2.1 预处理的概念与作用
2.1.1 预处理的概念
预处理是指在程序源代码被翻译为目标代码的过程中,由预处理器对程序源代码文本进行处理,生成二进制代码之前的过程。这个过程并不对程序的源代码进行解析,其操作的对象为以字符#开头的命令,包括#include的头文件、#define的宏定义等。
2.1.2 预处理的作用
预处理的过程中,预处理器会根据预处理指令读取头文件中用到的库的代码,并直接插入到程序文件中,即指示修改源代码并将新的文本保存在hello.i的过程,比如:对于宏定义来说,会完成对宏定义的替换;注释会直接删除等。
预处理程序读入所有包含的文件以及待编译的源代码,然后生成源代码的预处理版本。它能让编译器对文本进行编译的过程中,由于已经完成对库函数的访问,所以编译更加高效,减轻了编译器的工作。
2.2在Ubuntu下预处理的命令
命令 gcc -E hello.c -o hello.i

图2-1 预处理命令执行结果
2.3 Hello的预处理结果解析

图2-2 hello.c文件打开

图2-3 hello.i文件打开

图2-4 hello.c文件中的注释和#include命令

图2-5 预处理对#include<stdio.h>的处理
打开hello.i文件之后,可以发现,注释已经全部删除,而且对stdio.h,unistd.h,stdlib.h都进行了展开,cpp会到默认的环境变量下寻找stdio.h,打开/usr/include/stdio.h,对此递归展开。
2.4 本章小结
本章主要研究了hello在执行过程中的预处理步骤以及通过实际检验探究预处理实现了什么。预处理是计算机对程序进行操作的第一个步骤,在这个过程中预处理器(preprocessor)会对hello.c文件根据预处理指令进行修改,对头文件、宏定义操作,将程序中涉及到的库中的代码补充到程序中;对注释进行操作,将注释删除,最后将初步处理完成的文本保存在hello.i中。

第3章 编译
3.1 编译的概念与作用
3.1.1 编译的概念
编译是编译器利用编译程序从源程序产生目标程序的过程,即把高级语言转化为汇编语言。在这个阶段编译器会完成对代码的语法和语义的分析,生成汇编代码,并将这个代码保存在hello.s文件中。
3.1.2 编译的作用
编译是是将高级语言程序解释成为计算机所需的详细机器语言指令集的的过程。计算机装载到寄存器的指令是以数字形式存储的,指令集中的每一条指令具有一个数字代码。计算机程序最终必须以这种数字指令代码(或称为机器语言)来表示,而汇编语言是中间的重要环节。
3.2 在Ubuntu下编译的命令
命令 gcc -S hello.i -o hello.s

图3-1 编译命令的执行结果
3.3 Hello的编译结果解析
文件中有如下字段:
.file C 文件声明
.text 代码段
.globl 声明全局变量
.data 已初始化的全局和静态C变量
.type 指明函数类型或对象类型
.section .rodata 只读数据段
3.3.1 数据类型解析
1.整型变量:main参数 int argc:
Argc是函数传入的第一个int的参数,存储在%edi中,表示输入参数的个数。

2字符串:
第二个字符串.LC1其中的两个%S对应与输入的两个参数:argv[1]和argv[2]。

3.3.2赋值:
对局部变量的赋值:
通过movl指令,利用寄存器和$0, -4(%rbp)指令对局部变量赋值

3.3.3算术操作
Hello.c中的主要的算术操作为循环增加(i++)
编译器将i++翻译为addl$1,-4(%rbp)

3.3.4关系操作
Hello.c中的主要的算术操作为循环的控制,编译器将i<8翻译为$7,4(%rbp)

3.3.5控制转移
hello.c内部的控制转移主要有if语句以及for循环内部的控制转移
1.for(i=0;i<8;i++):
for循环的控制时比较cmpl $7, -4(%rbp) ,当i大于9时跳出循环,否则进入循环体执行
2.if(argc != 4):
当argc不等于4时跳转执行实现if的判断。首先使用cmpl $4, -20(%rbp),设置条件码,使用je判断ZF标志位,如果为0,说明argv-4=0 argv==4,则不执行if中的代码直接跳转到.L2,否则顺序执行下一条语句,即执行if中的代码。

3.3.6函数操作
hello.c内部主要有5个函数:main(),printf(),exit(),atoi(),sleep(),getchar()
3.4 本章小结
本章主要研究了编译的概念和作用,通过gcc -S hello.c -o hello.s生成了编译后的文件。对于生成的.s文件,分析了相关数据的处理,编译是后续处理的基础

第4章 汇编
4.1 汇编的概念与作用
4.1.1 汇编的概念
汇编指的是汇编器将hello.s翻译成机器语言指令的过程,计算机把指令打包成可重定位目标文件,并保存在hello.o文件中(一个二进制文件,是程序执行的机器指令)。也就是用汇编语言编写的源代码,通过相应的汇编程序将它们转换成可执行的机器代码。
4.1.2 汇编的作用
将汇编语言编写的源代码翻译成可以供机器执行的二进制代码,使程序能够在链接环节之后被计算机直接执行。
4.2 在Ubuntu下汇编的命令
命令 gcc -c hello.s -o hello.o

图4-1 汇编执行结果
4.3 可重定位目标elf格式
使用命令 readelf -a hello.o > hello_o_elf.txt,将hello.o文件的ELF格式保存到hello_o_elf_txt中。
4.3.1 ELF头
如图4-2所示,ELF头最开头是16个字节的e_ident, 其中包含用以表示ELF文件的字符,以及其他一些与机器无关的信息。开头的4个字节值固定不变,为0x7f和ELF三个字符,描述了生成该文件的系统的字的大小和字节顺序。ELF头剩下的部分包含帮助链接器分析的信息,包括ELF头的大小、目标文件的类型、机器类型等。它描述的是一个段在文件中的位置、大小以及它被放进内存后所在的位置和大小。

图4-3 hello.o的ELF头
4.3.2 符号表

图4-4 符号表
用来存放定义和引用的函数和全局变量的信息。
4.3.3 重定位节

图4-5 重定位节
将EFL文件中的未定义符号关联的处理过程。
4.3.4 节头表

图4-6 头节表
每一节的含义分别是:
.text:已编译程序的机器代码
.rela.text:一个.text节中位置的列表,链接器链接其他文件时,需进行修改
.data:已初始化的全局和静态C变量
.bss:未初始化的全局和静态C变量和所有被初始化为0的全局或静态变量
.rodata:只读数据段
.comment:版本控制信息
.note.GNU-stack:注释信息,有独立的格式
.symtab:符号表
.strtab:字符串表
.shstrtab:节区名称
4.4 Hello.o的结果解析
命令:objdump -d -r hello.o>hello.objdump
分析hello.o的反汇编,并与第3章的hello.s进行对照分析。

图4-7 hello.s            图4-8 hello.objdump
1.分支转移
反汇编语言中,跳转指令的操作数不采用段名称,段名称是在汇编语言中便于编写的助记符,在汇编成机器语言之后采用具体的地址。
2.函数调用
在hello.s文件中,函数调用时直接写函数名称,但在反汇编hello.objdump文件中,call的目标地址是当前位置下一条指令。这是动态链接导致的。
4.5 本章小结
本章通过hello程序从hello.s到hello.o的汇编过程,以及ELF格式的分析,并将hello.s和hello.objdump对比,说明了汇编的作用,实现的目标,以及汇编语言映射到机器语言的区别和转换过程。
第5章 链接
5.1 链接的概念与作用
5.1.1 链接的概念
链接是指通过链接器将文件中调用的函数和库的链接,并将他们组成一个可执行整体,合成单一文件的过程,即生成可执行文件。可执行文件加载后可以被执行。
5.1.2 链接的作用
实现库函数组合到目标可执行程序中,解析未定义符号引用。链接这个过程将不能直接执行的目标代码变成可执行程序。
5.2 在Ubuntu下链接的命令
命令:
ld -o hello -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 hello.o /usr/lib/x86_64-linux-gnu/libc.so /usr/lib/x86_64-linux-gnu/crtn.o

图5-1 执行链接命令后生成可执行文件hello
5.3 可执行目标文件hello的格式
命令:readelf -a hello > hello.elf
将hello的ELF格式保存至hello.elf中。

图5-2 链接后ELF头
与hello.o中基本一致。

图5-3 链接后的节头表
可以看出可执行文件hello中的各个节的信息。链接后较之于链接前,节的数目增多,说明在链接过程中添加了新的东西。
5.4 hello的虚拟地址空间

图5-4 节头表和虚拟地址空间
5.5 链接的重定位过程分析
命令:objdump -d -r hello>hello.objdump1,得到hello的反汇编文件

图5-5 hello的反汇编结果

图5-6 hello.o的反汇编结果

  1. 链接过程
    链接命令中,动态链接器是64的/lib64/ld-linux-x86-64.so.2,定义了程序入口(调用main),初始函数;libc.so是动态链接共享库,将部分函数在链接阶段加入。
  2. 重定位项目
    重定位分为三个阶段,第一个阶段修正地址,确定函数和数据的位置,将符号和引用关联起来,第二个阶段合并模块,成为新的节;第三个阶段是符号的重定位,确定地址。
    5.6 hello的执行流程
    (以下格式自行编排,编辑时删除)
    使用edb执行hello,说明从加载hello到_start,到call main,以及程序终止的所有过程。请列出其调用与跳转的各个子程序名或程序地址。
    程序名称 程序地址
    ld-2.27.so!_dl_start 0x7fce:8cc38ea0
    ld-2.27.so!_dl_init 0x7fce:8cc47630
    hello!_start 0x400500
    libc-2.27.so!__libc_start_main 0x7fce:8c867ab0
    -libc-2.27.so!__cxa_atexit 0x7fce:8c889430
    -libc-2.27.so!__libc_csu_init 0x4005c0
    hello!_init 0x400488
    libc-2.27.so!_setjmp 0x7fce:8c884c10
    hello!main 0x400532
    hello!puts@plt 0x4004b0
    hello!exit@plt 0x4004e0
    *hello!printf@plt ——
    *hello!sleep@plt ——
    *hello!getchar@plt ——
    ld-2.27.so!_dl_runtime_resolve_xsave 0x7fce:8cc4e680
    -ld-2.27.so!_dl_fixup 0x7fce:8cc46df0
    –ld-2.27.so!_dl_lookup_symbol_x 0x7fce:8cc420b0
    libc-2.27.so!exit 0x7fce:8c889128
    5.7 Hello的动态链接分析
    分析hello程序的动态链接项目,通过edb调试,分析在dl_init前后,这些项目的内容变化。要截图标识说明。
    5.8 本章小结
    本章分析了链接过程中对程序的处理,ELF格式,具有的节等。经过链接,ELF可重定位的目标文件变成可执行的目标文件,利用动态库等相关信息,将地址进行重定位,从而保证寻址的正确进行。链接后,程序便能直接运行。

第6章 hello进程管理
6.1 进程的概念与作用
进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
6.2 简述壳Shell-bash的作用与处理流程
1.作用:是一个命令解释器,对用户命令进行解释。
2.处理流程:检查内部命令,在可执行目录表寻找应用程序,然后寻找可执行文件,如果能 找到,就把应用程序传回。
6.3 Hello的fork进程创建过程
终端输入./hello 1181200214 zhangyusong,这不是一个内置命令,所以加载可执行文件hello。
此时创建子进程。
6.4 Hello的execve过程
6.5 Hello的进程执行
结合进程上下文信息、进程时间片,阐述进程调度的过程,用户态与核心态转换等等。
6.6 hello的异常与信号处理
hello执行过程中会出现哪几类异常,会产生哪些信号,又怎么处理的。
可能会出现中断,终止。
程序运行过程中可以按键盘,如不停乱按,包括回车,Ctrl-Z,Ctrl-C等,Ctrl-z后可以运行ps jobs pstree fg kill 等命令,请分别给出各命令及运行结截屏,说明异常与信号的处理。
6.7本章小结
本章中主要从进程的概念以及进程在计算机中的调用过程入手,介绍了shell的作用和处理流程,执行hello时的fork和execve过程。对hello进程的执行和异常处理行分析。

第7章 hello的存储管理
7.1 hello的存储器地址空间
逻辑地址:程序的段内偏移。
线性地址:虚拟地址到物理地址变换的中间层
虚拟地址:由程序产生的由段选择符和段内偏移地址组成的地址。
物理地址:地址总线上寻址物理内存的地址信号,是地址的最终结果。
7.2 Intel逻辑地址到线性地址的变换-段式管理
一个逻辑地址由两部份组成,段标识符和段内偏移量。
段标识符是由一个16位长的字段组成,称为段选择符。其中前13位是一个索引号。

每一个段描述符由8个字节组成:

对于一个给定的完整逻辑地址[段选择符:段内偏移地址],首先看段选择符的T1是0还是1,即是转换的目标是GDT中的段,还是LDT中的段,再根据相应寄存器,得到地址和地址的大小,这样就得到一个数组。其次拿出段选择符中前13位,可以在这个数组中,查找到对应的段描述符,这样就得到了基地址。最后结合Base和offset就得到了线性地址。
7.3 Hello的线性地址到物理地址的变换-页式管理
这种变换的基本原理是把线性地址分成固定长度的单元,称为页,然后把页内部连续的线性地址映射到连续的物理地址中。
在实模式下,逻辑地址=线性地址=实际的物理地址。段寄存器存放真实段基址,同时给出32位地址偏移量,则可以访问真实物理内存。
在保护模式下,控制寄存器CR0的最高位PG位控制着机制是否生效,如果PG=1,分页机制生效,需通过页表查找才能把线性地址转换物理地址。如果PG=0,则分页机制无效,线性地址就直接作为物理地址。
7.4 TLB与四级页表支持下的VA到PA的变换
CPU产生虚拟地址VA,VA传送给MMU,MMU使用前36位VPN作为TLBT(前32位)+TLBI(后4位)向TLB中匹配。若命中,则得到PPN(40bit)与VPO(12bit)组合成PA(52bit);若TLB中没有命中,MMU向页表中查询,CR3确定第一级页表的起始地址,VPN1(9bit)确定在第一级页表中的偏移量,查询出PTE,如果在物理内存中且权限符合,确定第二级页表的起始地址,以此类推,最终在第四级页表中查询到PPN,与VPO组合成PA,并且向TLB中添加条目。
7.5 三级Cache支持下的物理内存访问

利用物理地址按组索引,每组8路,进行匹配,如果匹配成功,标志返回为1,则命中,然后将数据取出写回。如果匹配不成功,则不命中,然后向下继续查找L2cache,L3cache,主存,如果有空闲位置,直接放置,如果冲突,则进行替换。
7.6 hello进程fork时的内存映射
Fork函数被调用时,为新进程创建虚拟内存,创建当前进程的的mm_struct, vm_area_struct和页表的原样副本。两个进程的每个页面都标记为只读,区域结构标记为私有的写时复制。当fork在hello中返回时,虚拟内存和和新进程相同。当任何一个进程执行写操作时,后面的写操作会通过写时复制机制创建新的页面。这样为每个进程保留私有空间地址。
7.7 hello进程execve时的内存映射
execve函数调用启动代码,在当前进程中加载并运行hello中的程序,用hello程序有效地替代了当前程序。加载hello的主要步骤是:首先删除当前进程虚拟地址的用户部分中的已存在的区域结构;接下来映射私有区域,为新程序的代码、数据、bss和栈区域创建新的区域结构,所有的新的区域都是私有的、写时复制的;然后映射共享区域,将程序与共享对象libc.so动态链接库链接,这样就映射到了hello的虚拟地址空间上的共享区域里;最后要设置当前进程的程序计数器,使之指向hello代码区域入口,这样下一次的hello进程就可以直接从入口进入了。

7.8 缺页故障与缺页中断处理
缺页故障是一类常见故障,指的是在执行一条指令时,如果发现他要访问的页没有在内存中(存在位为0),那么停止该指令的执行,并产生一个页不存在异常,对应的故障处理程序可通过从外存加载加载该页到内存的方法来排除故障,之后,原先引起的异常的指令就可以继续执行,而不再产生异常。处理方法是:将控制传递给处理程序,然后进行故障处理程序运行,最后处理陈旭执行当前指令。
缺页中断处理:缺页中断就是要访问的页不在主存,需要操作系统将其调入主存后再进行访问。当进程执行过程中发生缺页中断时,需要进行页面换入。
7.9动态存储分配管理
Printf会调用malloc,请简述动态内存管理的基本方法与策略。
基本方法有两种:一是显示内存管理EMM,在EMM方式,内存从堆中进行分配,用完后手动回收。程序使用malloc()函数分配整数数组,并使用free()函数释放分配的内存。二是自动内存管理AMM,AMM也可叫垃圾回收器,与EMM不同,关注已分配的内存空间,一旦不再使用,立即回收。
策略有两种,分别利用显示空闲链表和隐式空闲链表。
7.10本章小结
本章重点研究存储器的地址空间,包括虚拟地址,物理地址,线性地址和逻辑地址,VA到PA的变换,三级Cache支持下的物理内存访问,进程fork和execve时的内存映射,缺页故障和动态存储分配管理方法及原理。

第8章 hello的IO管理
8.1 Linux的IO设备管理方法
设备的模型化:文件
设备管理:unix io接口
所有的设备都被模块化为文件,输入和输出当成简单的读写。而在linux下,有一个简单的接口unix IO,它将输入和输出统一成一种执行方式,便于管理。
8.2 简述Unix IO接口及其函数
Linux将设备映射为文件,以文件的方式对I/O设备进行读写。对文件的操作,内核提供了一种简单、低级的应用接口,即Unix I/O接口。通过接口,可以通过打开文件、改变文件位置、读写文件、关闭文件等实现输入和输出。
函数:打开文件:int open(char *filename, int flags, mode_t mode);
关闭文件:int close(int fd);
读文件:ssize_t read(int fd, void *buf, size_t n);
写文件:ssize_t write(int fd, const void buf, size_t n);
8.3 printf的实现分析
https://www.cnblogs.com/pianist/p/3315801.html
printf函数的实现是

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

调用了read函数,读取缓冲区。
异步异常-键盘中断的处理:键盘中断处理子程序。接受按键扫描码转成ascii码,保存到系统的键盘缓冲区。
getchar等调用read系统函数,通过系统调用读取按键ascii码,直到接受到回车键才返回。
8.5本章小结
本章研究了Linux的IO设备管理机制,Unix IO接口及其提供的函数,并分析了printf和getchar两个函数的实现机制。
结论
Hello程序,在通过输入输出设备被编写进hello.c,然后开始了运行的过程。首先是预处理,预处理器将外部函数展开,合并到hello.i中,它被编译器编译成汇编文件hello.s,随后经历汇编,变成可重定位文件hello.o,链接器链接,将可重定位文件与动态链接库链接,这样就可以运行了。Shell调用fork创建子进程,然后调用execve函数启动加载,映射虚拟内存,运行程序,然后执行指令,访问内存,动态申请内存,最后shell回收hello进程,内核删除为hello进程创建的所有数据结构。

附件
列出所有的中间产物的文件名,并予以说明起作用。
文件名称 文件说明
hello.c hello源文件
hello.i 预处理后文本文件
hello.s 编译得到的汇编文件
hello.o 汇编后的可重定位目标文件
hello 链接后的可执行文件
hello.objdump1 hello可执行文件反汇编代码
hello.elf hello的elf文件
hello.objdump hello.o(链接前)的反汇编文件
hello_o_elf.txt hello.o的ELF格式

参考文献

[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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值