helloworld經歷了什麼?

《深刻理解計算機系統》學習筆記

hello world每每是學習編程時遇到的第一個示例,下面是一個C語言版本:linux

#include <stdio.h>

int main()
{
    printf("hello, world\n");
    return 0;
}

這個程序會在終端打印hello, world這串字符,那麼這個程序在咱們的計算機上究竟是怎能被讀取運行的呢?編程

程序的存儲

咱們將這段代碼保存爲文本文件並命名爲hello.c,稱做源程序或源文件。這段代碼裏都是英文字母以及一些符號,然而,計算機內存儲的信息都是二進制的,計算機只能識別由10組成的位(比特)序列,每8個位組成一個字節。那麼英語有26個字母,漢字更是成千上萬個,只用0和1怎麼表示呢?不用怕,咱們只要將不少個0與1排列組合一下就能表示不少個了,n位就能表示2n個文字。例如一個字節8位最多就能表示256個。這就是編碼的強大能力了,常見的編碼標準有ASCII和UTF-8。
ascii低128位對照表函數

程序被翻譯成不一樣格式

C語言是高級語言,要想在計算機上運行,就必須被翻譯成計算機能理解的機器語言指令。而後這些指令按一種稱爲可執行目標程序的格式打好包,並以二進制磁盤文件的形式存放起來。目標程序也稱可執行目標文件
linux> gcc -o hello hello.c
在Linux上咱們用GCC將hello.c翻譯稱可執行文件hello,這個過程能夠分爲四個階段。
編譯系統學習

  • 預處理階段:預處理器cpp根據以井號#開頭的預處理命令修改原始程序。例如這裏hello.c的第一行#include <stdio.h>告訴預處理器讀取頭文件stdio.h的內容(這個文件裏包含了printf這個函數)並把它插入源程序,獲得hello.i
  • 編譯階段:編譯器ccl將hello.i翻譯成文本文件hello.s,這裏包含一個彙編語言程序:
main:
  subq    $8, %rsp
  movl    $LC0, %edi
  call    puts
  movl    $0, %eax
  addq    $8, %rsp
  ret
  • 彙編階段:彙編器as將hello.s翻譯成機器語言指令,把這些指令打包成一種叫作可重定位目標程序的格式,並將結果保存到hello.o
  • 連接階段:咱們在程序裏用到了printf函數,它存在於一個名爲printf.o的預編譯好了的文件中。這個文件須要以某種方式合併到咱們的程序中,這就要用到連接器ld。結果就獲得可執行文件hello。能夠被加載到內存由系統執行。
相關文章
相關標籤/搜索