标签:
#include <stdio.h> int main() { printf("Hello World\n"); }
上面是一个c语言的hello world程序,虽然少了return 0, 但这对本文的主题没有影响。上面的hello.c程序是以一系列的bytes(1byte = 8bits)形式在文件中存在,每一个byte有个整数值,对应一个字符,而这个整数值叫做ASCII码,由ASCII码组成的文件叫做text files.其余的文件叫做binary files。
程序被其他的程序翻译成不同的形式:
源程序hello.c(text)会先被预处理器修改为hello.i(text), 比如:预处理器会根据指令#include<stdio.h>,把stdio.h头文件的内容直接插入到文件中。
被修改后的hello.i随后被编译器编译为hello.s(汇编语言text)。
hello.c再被assembler汇编译器编译为hello.o(机器语言binary)
最后,由于函数中有printf()函数,该函数属于c标准库,该函数在一个分开的预编译文件中叫做printf.o,要生成可执行文件,必须由Linker(连接器)把hello.o 和 printf.o文件链接起来,最后就生成了可执行文件hello.
如何执行以上的过程呢?
在我的mac os系统中,首先打开Terminal(终端), 然后在终端中用cd 命令定位到当前的文件位置,然后在终端中输入gcc -o hello hello.c即可完成以上的所有编译过程,并且生成可执行文件hello, 注意:这条语句中,gcc -o hello hello.c 中间的hello代表生成的可执行文件的名字。
如何运行可执行文件?
完成以上步骤后,只需要在终端输入./hello即可在终端上打印出hello world了,也可以通过双击可执行文件的额方法完成运行。
在我们的电脑中是如何运行可执行文件的呢?
电脑一般由以下几部分组成:
1. CPU(Central Processing Unit), 也可以叫做Processor.
主要由:register file, PC(program counter), ALU(Arithmetic/Logic Unit), USB(Universal Serial Bus) 构成,主要功能是:
执行存储在内存中的指令。它的核心是一个以word-sized(一个字大小)为基本单位的存储设备(or register), 叫做program counter(pc),在运行的任意时刻,pc 都指向一个在内存中的指令,当执行完当前指令后,pc移动到下一个指令。
2. Main memory(内存)
内存是一个临时的存储设备,当CPU运行的时候,内存用来临时存储程序和数据,当程序执行完,这些程序和数据都被内存清除,
3. Buses(传输的线路)
Buses 是用来传输数据的线路,Buses能传输固定大小的words, 一个word中的bytes在不同机器上的不同,有的是4bytes(32bits), 有的是8bytes(64bits), 并且我们假设buses 每次传输一个word.
4. I/O Devices(输入输出设备)
输入输出设备是系统与外界联系的桥梁,常见的I/O设备:键盘,鼠标,屏幕,磁盘(disk).
每一个I/O设备都通过controller或者adapter(适配器)与I/O Bus相连接,其中,controller和adapter的主要区别是,controller主要是直接在motherboard(main printed circuit board)上面,而adapter是一张插在motherboard上面的卡片
接下来回到重点,电脑运行可执行文件的过程是怎样的呢?
当我们在Terminal上面输入./hello之前,shell program(外壳程序)正在执行"等待我们输入"的指令,当我们键入"./hello"的时候,shell program把每一个字符通过Bus读入CPU中的register, 然后把指令存储在内存中。
当我们键入"enter"的时候,shell知道我们已经完成键入了,于是通过执行一系列指令把我们的可执行文件hello中的code和data通过磁盘(disk)复制到内存(memory).
当hello中的code和data被载入内存中后,CPU(processor)开始执行在main中的一系列的机器指令,通过指令把字符串"hello, world\n"复制到register file中,并且最终传输到输出设备----屏幕。
标签:
原文地址:http://blog.csdn.net/myhelperisme/article/details/42424865