天天看點

讀書筆記Pt.4——《深入了解計算機系統》

目錄

  • ​​傳統藝能????​​
  • ​​資料大小????​​
  • ​​尋址與位元組順序????​​
  • ​​整數表示????​​
  • ​​無符号數的編碼????​​
  • ​​補碼編譯????​​

傳統藝能????

小編是雙非大學大一菜鳥不贅述,歡迎大佬指點江山

此前部落格​​點我!點我!請搜尋部落客 【知曉天空之藍】​​

喬喬的gitee代碼庫(打灰人 )​​歡迎通路,點我!​​

????????非科班轉碼社群誠邀您入駐????????

小夥伴們,打碼路上一路向北,背後煙火,彼岸之前皆是疾苦

一個人的單打獨鬥不如一群人的砥砺前行

這是我和夢想合夥人組建的社群,誠邀各位有志之士的加入!!

社群使用者好文均加精(“标兵”文章字數2000+加精,“達人”文章字數1500+加精)

直達: ​​社群連結點我​​

????????????傾力打造轉碼社群微信公衆号,等你加入!????????????

讀書筆記Pt.4——《深入了解計算機系統》

資料大小????

計算機和編譯器支援多種不同資料類型,整型浮點數這些的,許多機器都有處理單個位元組的指令,也有處理2,4,8位元組的整數的指令。

C語言的 char 類型表示一個單獨的位元組,盡管 char 是字面上用于存儲單個字元,但他也可以用來存儲整數值。我在C語言入門就已經展示了不同資料類型配置設定的位元組數:

讀書筆記Pt.4——《深入了解計算機系統》

随着64位機器的普及,程式移植到新機器上時,隐藏的對字長的依賴性就會顯現出來稱為錯誤,比如假設一個聲明為 int 的程式被用來存儲指針,在 32 位機器上可能是可行的,但在64位機器上就會完犢子。

讀書筆記Pt.4——《深入了解計算機系統》

尋址與位元組順序????

對于跨越了多位元組的程式,我們必須有對應的兩套标準:對象位址和存儲器中的排列方式。幾乎所有機器上多位元組都被存儲為連續的位元組序列,位址為所使用位元組中最小位址,比如一個 int x 的位址為0x100,也就是&x的值為0x100,那麼他的四個位元組就被配置設定在了0x100,0x101,0x102,0x103的位置。

排清單示一個對象的位元組有兩個通用規則,不扯那些難懂的書面語,說白了就是我們之前學習的大小端模式。有的機器會選擇從低有效位元組到最高有效位元組存儲,有些則恰恰相反。最低有效位元組位于前面的方式就是小端法,最高有效位元組位于前面就是大端法。現在許多前沿的微處理器使用雙端法,即可以自行配置作為大端或者小端使用。

讀書筆記Pt.4——《深入了解計算機系統》

大端和小端的起源其實是源自于《格列佛遊記》中的雞蛋問題,書中人民對于雞蛋該從哪邊剝變現的十分情緒化,現實中也和雞蛋問題一樣,位元組順序規劃并沒有技術上的原因。

雖然不同類型機器編譯會得到相同結果,但是通過網絡傳輸二進制資料時小端的資料發送到大端會反序,所有網絡程式的代碼必須遵循建立的标準其次,閱讀位元組序列時位元組的順序也很重要,比如我們從檔案裡摘出這個代碼:

讀書筆記Pt.4——《深入了解計算機系統》

這是由反彙編産生的代碼,反彙編器就是确定程式檔案所表示的指令序列的工具,,我們隻需要注意裡面的16進制位元組串 01 05 64 94 04 08,它是指令的位元組級表示,這條指令将一個字長資料放到位址 0x8049464 的值上,取出後面4位位元組(一個整型)反序得到 08 04 94 64,再去掉開頭的0就是 0x8049464。

位元組順序變得可見的第三種情況就是編寫規避正常的類型系統程式時。比如C語言裡面我們可以使用強制類型轉換來引用一個對象,而類型與實際定義不同,雖然大多數程式強烈不推薦這種技巧,但對于某些系統級程式設計是有用甚至必需的。

整數表示????

C語言支援多種整型資料類型——表示有限範圍的整數

讀書筆記Pt.4——《深入了解計算機系統》

這裡還給出了32位和64位機器的取值範圍。每種類型都可以用關鍵字來指定大小,同時還可以訓示對象是否為負如 unsigned,這些不同大小多少位元組數會根據機器的字長和編譯器有所不同,這裡唯一一個和機器有關的大小訓示符是 long,64位機器使用 8 個位元組表示是 32位 4 個位元組的兩倍。

我值得注意的是這些取值範圍并不是對稱的,負數會比整數大1,這是如何表示負數會講到的問題。C語言定義了每種資料必須能夠表示的最小取值範圍,而這些取值範圍(正負數)是對稱的。注意C和C++都支援有符号和無符号數而 JAVA 隻支援有符号數!

讀書筆記Pt.4——《深入了解計算機系統》

無符号數的編碼????

因為符号和标注鍵盤實在扣不出來,這裡就貼個圖吧

讀書筆記Pt.4——《深入了解計算機系統》

上面 2^i 的條狀表示來反映每個位的位置 i 每個位向量就等于值為1的位對應的長度之和,我們以 w = 4 的無符号數為例

讀書筆記Pt.4——《深入了解計算機系統》

考慮一下 w 位能表示的值的範圍,最小值用位向量 [000……0]表示,最大位[111……1]表示,w = 4時,UMax = 2^4 -1 = 15,是以就會定義出一個最大值為 15 的映射。

無符号數的二進制表示是一個很重要的屬性,每個介于0~(2^w) - 1的數都有唯一一個 w 位的值編碼。比如十進制的 11,隻有一個 4 位的表示:[1011],這個屬性就是指函數是一個雙射——每個長度為 w 的位向量都有一個唯一值與它對應,反過來每個介于0~(2^w) - 1的數都有唯一一個 w 位的位向量與它對應。

補碼編譯????

對于許多應用我們還希望能夠表示負數值,常見的表示方式就是補碼形式

在補碼的定義中,将字的最高有效位解釋為負權,他也可以函數表示:

讀書筆記Pt.4——《深入了解計算機系統》

我和用向左指的條表示符号位的負權重,是以位向量關聯的數值可以由向左指的條相加決定,其實和上面無符号數編碼是一樣的:

讀書筆記Pt.4——《深入了解計算機系統》

作用原理也和無符号數是一樣的,比如給出一個 w = 4 為例,TMin = B2T_4([1000]) = -2^3 = -8,而TMax = B2T_4([0111]) = 22+21+2^0 = 7。

那麼關于這些數字,有幾點需要注意:

  1. 補碼範圍不對稱,|TMax|+1 = |TMin|,也就是說 TMin 沒有與之對應的正數,這就造就了補碼的一些特殊屬性且容易造成一些細微錯誤。其原因因為一半的數符号位 1 表示負數,而一半的數符号位 0 表示非負數,摳掉 0 這個小特殊就會讓 正數少一個。
  2. 最大的無符号數值剛好比補碼最大值兩倍大一點:UMax = 2*TMax + 1;補碼中所有表示負數的位模式在無符号數裡面全變成了正數。
讀書筆記Pt.4——《深入了解計算機系統》

C語言并沒有規定要補碼來表示有符号整數,但幾乎所有機器都這麼幹了,因為我們希望代碼具有最大可移植性,其次是許多程式的有符号數都假設用補碼來表示。C語言庫裡面頭檔案<limits.h>定義了一組常量來限制機器中不同整型的取值範圍,比如 INT_MAX,INT_MIN 和 UINT_MAX就描述了有符号和無符号整數的範圍,一台機器 int 類型如果有 w 位 ,這些常量就對應了 TMax,TMin 和 UMax 的值。

繼續閱讀