重學計算機組成原理(4)-還記得紙帶編程嗎?

      網友投稿 795 2022-05-29

      以前寫程序用“打孔卡(Punched Card),沒法像今天,掏出鍵盤就能打字,而是要先在腦海/紙寫出程序,然后在紙帶/卡片上打洞。這樣,要寫的程序、要處理的數據,就變成一條條紙帶或者一張張卡片,之后再交給當時的計算機去處理。

      上世紀60年代晚期或70年代初期,Arnold Reinold拍攝的FORTRAN計算程序的穿孔卡照片

      人們在特定的位置上打洞或者不打洞,來代表“0”或者“1”。

      計算機或說CPU本身,并沒有能力理解這些高級語言,即使在2019年的今天,我們使用的現代個人計算機,仍然只能處理所謂的“機器碼”,也就是一連串的“0”和“1”這樣的數字。

      那高級語言的程序,最終是怎么變成一串串“0”和“1”的?

      這一串串“0”和“1”又是怎么在CPU中處理的?

      1 軟硬件接口中,CPU做了啥?

      CPU(Central Processing Unit,中央處理器)就是計算機的大腦

      硬件的角度

      一個超大規模集成電路,通過電路實現了加法、乘法乃至各種各樣的處理邏輯。

      軟件工程師的角度

      一個執行各種計算機指令(Instruction Code)的邏輯機器

      這里的計算機指令,就好比一門CPU能夠聽得懂的語言,即機器語言(Machine Language)

      不同的CPU能夠聽懂的語言不太一樣

      Intel的CPU、ARM的CPU兩者能聽懂的語言就不一樣,這樣兩種CPU各自支持的語言,就是兩組不同的計算機指令集(Instruction Set)。

      “Set”就是數學上的集合,代表不同的單詞、語法。如果在自己電腦上寫一個程序,然后把這個程序復制一下,裝到自己的手機上,肯定是沒辦法正常運行的,因為這兩者語言不通。

      而一臺電腦上的程序,簡單復制一下到另外一臺電腦上,通常就能正常運行,因為這兩臺CPU有著相同的指令集,它們語言相通。

      存儲程序型計算機(Stored-program Computer)

      計算機程序,不可能只有一條指令,而是成千上萬條指令組成

      但CPU不能一直放著所有指令,所以程序平時是存儲在存儲器

      這種程序指令存儲在存儲器里面的計算機,我們就叫作

      Plugboard Computer

      在沒有現代計算機之前,有著聰明才智的工程師們,早就發明了一種叫Plugboard Computer的計算設備

      在一個布滿了各種插口和插座的板子上,工程師們用不同的電線來連接不同的插口和插座,從而來完成各種計算任務

      IBM的Plugboard

      2 編譯=>匯編 代碼=>機器碼

      代碼是怎么變成一條條計算機指令,最后被CPU執行的?

      test.c

      編譯(Compile)成匯編代碼

      要讓這段程序在Linux跑起來,需要把整個程序翻譯成匯編語言(ASM,Assembly Language)的程序

      針對匯編代碼,可以再用匯編器(Assembler)翻譯成機器碼(Machine Code)

      這些機器碼由“0”和“1”組成的機器語言表示,這一條條機器碼,就是一條條的計算機指令

      這樣一串串的16進制數字,就是我們CPU能夠真正認識的計算機指令。

      在Linux上,可使用gcc和objdump,把對應的匯編代碼和機器碼都打印出來。

      左側一堆數字,就是一條條機器碼

      右邊一系列的push、mov、add、pop等,這些就是對應的匯編代碼

      一行C語言代碼,有時候只對應一條機器碼和匯編代碼,有時候則是對應兩條機器碼和匯編代碼

      匯編代碼和機器碼之間是一一對應的。

      實際在用GCC(GUC編譯器套裝,GUI Compiler Collectipon)編譯器的時候,可直接把代碼編譯成機器碼,為什么還需要匯編代碼呢?

      那一串數字表示的機器碼,摸不著頭腦

      但即使你沒有學過匯編代碼,看的時候多少也能“猜”出一些這些代碼的含義。

      匯編代碼就是“給程序員看的機器碼”

      也正因為這樣,機器碼和匯編代碼是一一對應的

      很容易記住add、mov這些用英文表示的指令

      而8b 45 f8這樣的指令,由于很難一下子看明白是在干什么,所以會非常難以記憶

      從高級語言到匯編代碼,再到機器碼,就是一個日常開發程序,最終變成了CPU可以執行的計算機指令的過程。

      3 解析指令和機器碼

      了解了這個過程,下面我們放大局部,來看看這一行行的匯編代碼和機器指令,到底是什么意思。

      Intel CPU,有2000條左右的CPU指令,實在是太多了,沒法一一講解。不過一般來說,常見的指令可以分成五大類。

      算術類指令

      加減乘除,在CPU層面,都會變成一條條算術類指令

      數據傳輸類指令

      給變量賦值、在內存里讀寫數據,用的都是數據傳輸類指令。

      邏輯類指令

      邏輯上的與或非

      條件分支類指令

      日常的“if/else”

      無條件跳轉指令

      寫一些大一點的程序,我們常常需要寫一些函數或者方法

      在調用函數的時候,其實就是發起了一個無條件跳轉指令。

      匯編器是怎么把對應的匯編代碼,翻譯成為機器碼的。

      不同CPU有不同指令集,對應不同的匯編語言和不同的機器碼。

      為方便快速理解機器碼的計算方式,選用最簡單的MIPS指令集,看機器碼是如何生成的。

      MIPS是一組由MIPS技術公司在80年代中期設計出來的CPU指令集。最近,MIPS公司把整個指令集和芯片架構都完全開源了。想要深入研究CPU和指令集的同學,推薦一些資料。

      MIPS的指令是一個32位的整數,高6位操作碼(Opcode):

      代表這條指令具體是一條什么樣的指令。

      剩下的26位有三種格式,分別是:

      R指令

      一般做算術和邏輯操作,里面有讀取和寫入數據的寄存器的地址。如果是邏輯位移操作,后面還有位移操作的位移量。而最后的功能碼,則是在前面的操作碼不夠的時候,擴展操作碼表示對應的具體指令的。

      I指令

      通常是用在數據傳輸、條件分支,以及在運算的時候使用的并非變量還是常數的時候。這時,沒有位移量和操作碼,也沒有第三個寄存器,而是把這三部分直接合并成了一個地址值或者一個常數。

      J指令

      一個跳轉指令,高6位之外的26位都是一個跳轉后的地址

      add $t0,$s2,$s1

      下面都用十進制來表示對應的代碼,對應的MIPS指令的:

      opcode是0

      rs代表第一個寄存器s1的地址是17

      rt代表第二個寄存器s2的地址是18

      rd代表目標的臨時寄存器t0的地址是8

      因為不是位移操作,所以位移量是0

      把這些數字拼在一起,就變成了一個MIPS的加法指令。

      一般把對應的二進制數,用16進制表示。這里0X02324020。這個數字也就是這條指令對應的機器碼。

      回到開頭我們說的打孔帶

      打孔代表1

      重學計算機組成原理(4)-還記得紙帶編程嗎?

      沒有打孔代表0

      用4行8列代表一條指令來打一個穿孔紙帶,那么這條命令大概就長這樣:

      你應該學會了怎么作為人肉編譯和匯編器,給紙帶打孔編程了,不用再對那些用過打孔卡的前輩們頂禮膜拜了。

      4 總結

      打孔卡,其實就是一種存儲程序型計算機。

      只是這整個程序的機器碼,不是通過計算機編譯出來的,而是由程序員的人腦“編譯”成一張張卡片的

      對應的程序,也不是存儲在設備里,而是存儲成一張打好孔的卡片

      但是整個程序運行的邏輯和其他CPU的機器語言沒有什么分別,也是處理一串“0”和“1”組成的機器碼而已。

      我們看到了一個C語言程序,是怎么被編譯成為匯編語言,乃至通過匯編器再翻譯成機器碼的。

      除了C這樣的編譯型的語言之外,不管是Python這樣的解釋型語言,還是Java這樣使用虛擬機的語言,其實最終都是由不同形式的程序,把我們寫好的代碼,轉換成CPU能夠理解的機器碼來執行的。

      只是解釋型語言,是通過解釋器在程序運行的時候逐句翻譯,而Java這樣使用虛擬機的語言,則是由虛擬機對編譯出來的中間代碼進行解釋,或者即時編譯成為機器碼來最終執行。

      參考

      《計算機組成與設計:軟/硬件接口》第5版的2.17小節

      深入淺出計算機組成原理

      機器翻譯 匯編語言

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:Java并發編程基礎之線程應用實戰-基于線程池的簡單web服務器
      下一篇:禁止requestLegacyExternalStorage
      相關文章
      亚洲日韩亚洲另类激情文学| 亚洲国产精品无码久久久蜜芽| 久久久亚洲精品无码| 国产偷国产偷亚洲清高动态图| 亚洲 无码 在线 专区| 亚洲经典千人经典日产| 亚洲AV永久无码精品一福利| 亚洲日韩久久综合中文字幕| 亚洲图片激情小说| 亚洲啪啪免费视频| 亚洲入口无毒网址你懂的| 亚洲一级片在线观看| 亚洲午夜在线播放| 亚洲精品无码久久久久YW| 亚洲人成色99999在线观看| 亚洲国产精品无码久久九九大片| 亚洲精品中文字幕无码A片老| 亚洲乱亚洲乱妇24p| 狠狠综合亚洲综合亚洲色| 亚洲高清偷拍一区二区三区| 国产成人毛片亚洲精品| 在线观看亚洲成人| 亚洲精品国产成人片| 亚洲av激情无码专区在线播放| 久久久久亚洲AV无码专区首JN| 亚洲免费视频网址| 亚洲欧美一区二区三区日产| 免费亚洲视频在线观看| AV在线播放日韩亚洲欧| 亚洲精品亚洲人成人网| 久久久久亚洲av无码尤物| 亚洲精彩视频在线观看| 77777午夜亚洲| 日本亚洲高清乱码中文在线观看| 亚洲色偷偷综合亚洲AV伊人| 亚洲美女又黄又爽在线观看| 亚洲网站在线观看| 亚洲w码欧洲s码免费| 亚洲成a人片在线观看天堂无码 | 亚洲成A人片77777国产| 亚洲一区无码中文字幕|