HIT-ICS大作业

计算机系统大作业
题目:程序人生-Hello’s P2P
计算机科学与技术学院

摘 要

大作业题为程序人生-Hello’s P2P,围绕一个较简单的hello.c函数的整个生命周期展开,介绍了该示例程序从编写到执行到结束的全过程。详细地分析了每个阶段的具体操作过程,原理以及可能发生的一些异常情况等内容。将计算机系统的各个组成部分统一起来,并将所有学过的内容进行了整理与贯通。通过Linux中的命令行解析器shell进行操作,并使用了gdb、edb等调试工具,理论与实际相结合,并最终对计算机的体系结构有了更加深刻的认识。

关键词:编译系统;进程管理;存储管理;I/O管理

第1章 概述

1.1 Hello简介
Hello程序是许多程序员最早接触的程序,它的源程序如下:
图1-1
上面的源程序是许多IDE是直接默认生成的,程序员只需进行编译,程序即可运行,输出显示hello, world。尽管hello程序非常简单,但是为了让它实现运行,系统的每个主要组成部分都需要协调工作。hello程序的生命周期可概括为被程序员创建,在系统上运行,输出简单的消息,终止。
hello程序的生命周期是从一个高级C语言程序开始的,因为这种形式能够被人读懂。然后编译器驱动程序通过预处理,编译,汇编,链接四个阶段,将hello.c(program)翻译成一个可执行目标文件hello。hello文件存放在磁盘中,可以被加载到内存中,有系统执行。hello叫做程序(Program),用户通过shell,调用一系列函数将hello运行在内存中。他是通过一种叫做进程(Process)的抽象来实现的。
execve函数将hello加载至内存,顺着逻辑控制流,hello在硬件中取指译码执行,最终显示在屏幕上。最后程序终止,shell将子进程回收。
1.2 环境与工具

硬件环境 X64 CPU;2GHz;2G RAM;256GHD Disk 以上
软件环境 Windows7 64位以上;VirtualBox/Vmware 11以上;Ubuntu 16.04 LTS 64位/优麒麟 64位
开发工具 Visual Studio 2010 64位以上;Codeblocks
调试工具 gdb,edb,readelf

1.3 中间结果
列出你为编写本论文,生成的中间结果文件的名字,文件的作用等。
图1-2

中间结果文件名称 文件作用

hello.c hello源程序(文本)
hello.i 修改了的源程序(文本)
hello.s 汇编程序(文本)
hello.o 可重定位目标程序(二进制)
hello 可执行目标程序(二进制)
hello_o.elf 可重定位目标文件hello.o的ELF格式文件
hello.elf 可执行目标文件hello的ELF格式文件
helloo_obj.txt hello.o程序的反汇编文件
hello_obj.txt hello程序的反汇编文件

1.4 本章小结
这一章总结了整个实验的环境,使用的工具以及所有的中间结果,并且概述了hello程序的p2p以及020过程。

第2章 预处理

2.1 预处理的概念与作用
预处理阶段:预处理器(cpp)根据以字符#开头的命令,修改原始的C程序。比如hello.c中#include <stdio.h>命令告诉预处理器读取系统头文件stdio.h的内容,并把它直接插入程序文本中。结果就得到了另一个C程序,通常是以.i作为文件扩展名。

预处理的处理规则:
1.将所有的 “#define” 删除,并展开所有的宏定义
2.处理所有的条件预编译指令,比如:" #if #ifdef #elif #else #endif "
3.处理所有的 “#include” 预编译指令
4.删除所有的注释 “//”,“/* */”
5.添加行号和文件名标识,以便编译时产生的行号信息以及用于编译错误或警告时能够显示行号
6.保留所有的“#pragma”编译器指令

2.2在Ubuntu下预处理的命令
预处理命令:
gcc -E hello.c -o hello.i
图2-1
2.3 Hello的预处理结果解析
通过Gedit编辑器打开hello.c源程序:
图2-2
通过Gedit编辑器打开hello.i程序,并截取最后部分,如下图:
图2-3
发现修改后的hello.i程序从源程序hello.c中的23行增加到了3042行,main函数在hello.i的最后一部分。hello.i程序处理了所有的“#include”预编译指令,并且从最后的main函数可以看出,hello.i程序删除了所有的注释。
2.4 本章小结
这一章介绍了编译系统中的预处理阶段的概念,以及具体的操作,并且分析了预处理结果hello.i文件。预处理阶段即预处理器cpp将源程序文件hello.c与其相关的头文件(例如stdio.h)预处理成一个修改了的源文件(.i文件)。

第3章 编译

3.1 编译的概念与作用
编译阶段:编译器(ccl)将文本文件hello.i翻译成文本文件hello.s,它包含一个汇编语言程序。该程序包含函数main的定义,如下图所示(不完整):
图3-1
定义中的每条语句都以一种文本格式描述了一条低级机器语言指令。汇编语言是非常有用的,因为它为不同高级语言的不同编译器提供了通用的输出语言。
3.2 在Ubuntu下编译的命令
编译命令:
gcc -S hello.i -o hello.s

若直接从源文件(hello.c)到生成汇编语言文件(hello.s),则编译命令:
gcc -S hello.c -o hello.s
图3-2
3.3 Hello的编译结果解析
先分析hello.s文件的开头部分:
图3-3

.file “hello.c” 源文件名为hello.c
.text 代码段起始
.section .rodata 下面是.rodata节
.align 8 对齐方式为8字节
.string “\347\224\250\346\263\225: Hello \345……\201” 数据段中的字符串常量
.string “Hello %s %s\n” 数据段中的字符串常量
.text 代码段起始
.globl main 全局变量(标签main是一个可以在其它模块的代码中被访问的全局符号)
.type main, @function 指定是对象类型或者函数类型

再分析main函数部分:
图3-4
关于main函数参数的问题:
C语言规定main函数的参数只能有两个,习惯上这两个参数写为argc和argv。并且还规定了argc(第一个形参)必须是整型变量,argv(第二个形参)必须是指向字符串的指针数组。加上形参说明后,main函数的函数头应写为:
main (int argc,char *argv[])

关于atoi函数的问题:
atoi()是把字符串转换成整形数的一个函数。该函数会扫描参数nptr字符串,跳过前面的空白字符,例如空格,tab缩进等。
函数原型:int atoi(const char* nptr);
参数nptr:要进行转换的字符串;
返回值:返回一个int值,此值由将输入字符作为数字解析而生成。如果输入无法转换为该类型的值,则atoi的返回值为0。
说明:如果字符存在(跳过空格,全是空格返回0),是数字或者正负号则开始做类型转换,当出现一个字符不能识别为数字时(包括结束符\0),函数将停止读入字符串,返回整数值。否则,返回0。
图3-5
3.3.1数据:图3-6
3.3.2赋值操作:
对循环变量i赋值,采用如下movl语句:

3.3.3算术操作:
图3-7
3.3.4关系操作:
图3-8
3.3.5控制转移:
图3-9
3.3.6函数操作:
函数调用通过call指令来实现。call Q会把地址A压入栈中,并将PC设置为Q的起始地址。压入的地址A被称为返回地址,是紧跟在call指令后面的那条指令的地址。对应的指令ret会从栈中弹出地址A,并把PC设置为A。
图3-10
3.4 本章小结
这一章总结了编译阶段的概念及具体操作指令,最后分析了编译结果hello.s文件。该文件包含一个汇编语言程序,汇编语言中的每条语句都以一种文本格式描述了一条低级机器语言指令。
汇编语言是直接面向处理器的程序设计语言,它所操作的对象不是具体的数据,而是寄存器或者存储器,因此执行速度要比其他语言快,但同时也使得编程更加复杂。汇编语言总体特性为机器相关性、高速度与高效率以及编写和调试的复杂性。

第4章 汇编

4.1 汇编的概念与作用
注意:这儿的汇编是指从 .s 到 .o 即编译后的文件到生成机器语言二进制程序的过程。
汇编阶段:汇编器(as)将hello.s翻译成机器语言指令,把这些指令打包成一种叫做可重定位目标程序的格式,并将结果保存在目标文件hello.o中。hello.o文件是一个二进制文件,它包含程序的指令编码。如果在文本编辑器中打开hello.o文件,将看到一堆乱码。
4.2 在Ubuntu下汇编的命令
汇编命令:
gcc -c hello.s -o hello.o

若直接从源文件(hello.c)到生成可重定位目标文件(hello.o),则汇编命令:
gcc -S hello.c -o hello.o
图4-1
此时若用Gedit文本编辑器打开hello.o文件,将看到一堆乱码,如下图:
图4-2
4.3 可重定位目标elf

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值