標籤:
#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中,並且最終傳輸到輸出裝置----螢幕。
電腦系統學習筆記(1)-Hello World的一生。