HIT CSAPP 计算机系统大作业 《程序人生 - Hello’s P2P》

HIT CSAPP 计算机系统大作业 《程序人生 - Hello’s P2P》

计算机系统

大作业

题 目 程序人生-Hello’s P2P
专 业 软件工程
学   号 1173710104
班   级 1737101
学 生 滕涛    
指 导 教 师 吴锐

计算机科学与技术学院
2018年12月
摘 要
hello.c是每一个程序员所写出的人生中的第一个程序,但是不要看hello.c简短,其在计算机中运行却有着许许多多的奥妙值得每一个程序员去探索,由一个简单的程序开始去一步一步了解更加复杂且值得去探索的程序,才会得到一步一步的成长,这次的大作业就从hello开始第一步。
关键词:CSAPP;Hello程序;生命周期;

(摘要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简介
在Editor中键入代码得到hello.c程序,在linux中,hello.c经过cpp的预处理、ccl的编译、as的汇编、ld的链接最终成为可执行目标程序hello,在shell中键入启动命令后,shell为其fork,fork产生一个shell进程的子进程,于是Program变成Process,这是P2P(From Program to Process)的过程。之后shell为其execve,加载器为其分配内存空间,程序运行在物理内存中,CPU 为其分配时间片执行指令。当程序运行结束后,shell父进程负责回收hello进程,这便是020 (From Zero-0 to Zero -0)的过程。
1.2 环境与工具
硬件环境:Intel Core i7-7700HQ x64CPU,8G RAM,256G SSD +1T HDD. 软件环境:Ubuntu18.04.1 LTS
开发与调试工具:文字编辑器,gcc,as,ld,edb,readelf,HexEdit
1.3 中间结果
列出你为编写本论文,生成的中间结果文件的名字,文件的作用等。
文件名称 文件作用

hello.c 源代码
hello.i 预处理之后文本文件
hello.s 编译之后的汇编文件
hello.o 汇编之后的可重定位目标执行
hello 链接之后的可执行目标文件
hello2.c 测试程序代码
hello2 测试程序
helloo.objdmp Hello.o的反汇编代码
helloo.elf Hello.o的ELF格式
hello.objdmp Hello的反汇编代码
hello.elf Hellode ELF格式
hmp.txt 存放临时数据

1.4 本章小结
本章主要简单介绍了hello的p2p,020过程,列出了本次实验信息:环境、中间结果。
(第1章0.5分)

第2章 预处理
2.1 预处理的概念与作用
概念:预处理器cpp根据以字符#开头的命令,修改原始的C程序。主要功能如下:

  1. 将源文件中用#include形式声明的文件复制到新的程序中。比如hello.c 第 6-8 行中的#include<stdio.h> 等命令告诉预处理器读取系统头文件stdio.h unistd.h stdlib.h 的内容,并把它直接插入到程序文本中。结果就得到了另一个C程序,为hello.i。
    1. 用实际值替换用#define定义的字符串
    2. 根据#if后面的条件决定需要编译的代码

2.2在Ubuntu下预处理的命令
预处理指令及其生成结果

2.3 Hello的预处理结果解析
因为 hello.c 包含的头文件中还包含有其他头文件,因此系统会递归式的寻址和展开,直到文件中不含宏定义且相关的头文件均已被引入。故使用文字编辑器打开hello.i后发现main函数之前出现的是stdio.h , unistd.h和stdlib.h,以stdio.h的展开为例,cpp到默认的环境变量下寻找stdio.h,打开/usr/include/stdio.h 发现其中依然使用了#define 语句,cpp 对此递归展开,所以最终.i 程序中是没有#define 的。而且发现其中使用了大量的#ifdef #ifndef的语句,cpp 会对条件值进行判断来决定是否执行包含其中的逻辑。其他类似。
2.4 本章小结
本章主要介绍了预处理的定义与作用、并结合预处理之后的程序对预处理结果
进行了解析。

(第2章0.5分)

第3章 编译
3.1 编译的概念与作用
编译是利用编译程序从源语言编写的源程序产生目标程序的过程,也是用编译程序产生目标程序的动作。编译器将文本文件hello.i翻译成文本文件hello.s,它包含一个汇编语言程序。这个过程称为编译,同时也是编译的作用。
编译程序把一个源程序翻译成目标程序的工作过程分为五个阶段:词法分析;语法分析;语义检查和中间代码生成;代码优化;目标代码生成。

注意:这儿的编译是指从 .i 到 .s 即预处理后的文件到生成汇编语言程序

3.2 在Ubuntu下编译的命令
在这里插入图片描述
3.3 Hello的编译结果解析

3.3.1 汇编指令
指令 含义
.file 声明源文件
.text 声明代码段
.data 声明数据段
.section .rodata 以下是rodata节
.globl 声明一个全局变量
.type 声明指令及数据存放地址的对齐方式
.size 声明大小
.long、.string 声明一个long、string类型
.align 声明对指令或者数据的存放地址进行对齐的
方式
3.3.2 数据
一、字符串
汇编语言中,输出字符串作为全局变量保存,因此存储于. rodata 节中。汇编文件 hello.s 中,共有两个字符串,均作为 printf 参数,分别为:
在这里插入图片描述
1) “Usage: Hello 学号 姓名!\n”,第一个printf传入的输出格式化参数,在hello.s中声明,可以发现字符串被编码成UTF-8格式,一个汉字在utf-8编码中占三个字节,一个\代表一个字节。
2)“Hello %s %s\n”,第二个printf传入的输出格式化参数,在hello.s中声明

二、整型
在 hello.s文件中,sleepsecs 的定义如下:
在这里插入图片描述
程序中涉及的整数数据有:
1) int sleepsecs:sleepsecs 在 C 程序中被声明为全局变量,且已经被赋值,编译器处理时在.data节声明该变量,.data节存放已经初始化的全局和静态 C 变量。在图 3.3 中,可以看到,编译器首先将 sleepsecs在.text 代码段中将其声明为全局变量,其次在.data段中,设置对齐方式为 4、设置类型为对象、设置大小为 4 字节、设置为 long 类型其值为2。
2) int i:编译器将其值存储在寄存器或者栈空间中,两者选择具体决定于寄存器的数目以及优化程度,在 hello.s 编译器将 i 存储在栈上空间-4(%rbp)中,可以看出i占据了栈中的4B大小空间。编译器 ccl 会将 int 表示为 long 但对齐方式仍为 int 型的 4 字节,long 类型表示为双字 quad,对齐方式仍为 8 字节。
3) int argc:作为第一个参数传入
4) 立即数:其他整形数据的出现都是以立即数的形式出现的,直接硬编码在汇编代码中。

三、数组
在hello.c中运用数组如下
在这里插入图片描述
此部分循环对应汇编代码段为
在这里插入图片描述
argv[]为char类型单个数组元素的大小为8个字节起始地址为argv,传入的两个参数分别记为argv[1],argv[2],值为getchar()在函数运行时获取的两个%s,后通过指令取出了数组储存值。

3.3.3 赋值
hello.c文件中赋值操作共有两次:⑴int sleepsecs = 2.5 ⑵int i = 0
⑵ sleepsecs被定义为全局变量被定义为long类型,值为2
⑵ i的赋值通过mov操作来完成,即movl $0,-4(%rbp)
对于mov操作来说可分为movb(8位)、movw(16位)、movl(32位)、movq(64位)

3.3.4 类型转换
程序中涉及隐式类型转换的是:int sleepsecs=2.5,将浮点数类型的2.5强制转换为int类型。
当在double或float向int进行强制类型转换的时候,程序改变数值和位模式的
原则是:值会向零舍入。例如 1.999 将被转换成 1,-1.999 将被转换成-1。进一步
来讲,可能会产生值溢出的情况,与 Intel兼容的微处理器指定位模式[10…000]为整数不确定值,一个浮点数到整数的转换,如果不能为该浮点数找到一个合适的整数近似值,就会产生一个整数不确定值。
浮点数默认类型为double,所以上述强制转化是double强制转化为int类型。遵从向零舍入的原则,将2.5舍入为2。

3.3.5 算数操作
算数操作的汇编指令有
指令 效果
leaq S,D D=&S
INC D D+=1
DEC D D-=1
NEG D D=-D
ADD S,D D=D+S
SUB S,D D=D-S
IMULQ S R[%rdx]:R[%rax]=SR[%rax](有符号)
MULQ S R[%rdx]:R[%rax]=S
R[%rax](无符号)
IDIVQ S
R[%rdx]=R[%rdx]:R[%rax] mod S(有符号)R[%rax]=R[%rdx]:R[%rax] div S
DIVQ S R[%rdx]=R[%rdx]:R[%rax] mod S(无符号)
R[%rax]=R[%rdx]:R[%rax] div S
hello.s中的算数操作有:
⑵ i++ 在for循环中i累加,在hello.s中的汇编操作为addl $1,-4(%rbp)
⑵leaq指令中地址%rip被加上了.LC0,.LC1并分别传给了%rdi进行操作
leaq .LC0(%rip),%rdi 和 leaq .LC1(%rip),%rdi

3.3.6 关系操作
进行关系操作的汇编指令有:
指令 效果 描述
CMP S1,S2 S2-S1 比较-设置条件码
TEST S1,S2 S1&S2 测试-设置条件码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值