2013-03-30 20 views
2

爲什麼我們沒有4位大小的數據類型?如果我們如此傾向,爲什麼我們不能製造它們呢?我已經看到了比特場,但是我聽說它們不能攜帶,也許還沒有被使用?我認爲這是機器如何解釋鑽頭位置的位置值的結果。 (big-endian,little-endian)爲什麼編程語言嚴格依賴於原始類型,並且彙編更靈活?

typedef struct 
{ 
    int b1 : 1; 
    int b2 : 1; 
    .. 
    .. 
    .. 
    int b32 : 1; 
} bitfield32; 

我們也不能創建比任何原始類型都大的比特字段。那麼爲什麼這些限制?它可以在組裝中完成嗎?

+0

我們可以,不是問題。我們不這樣做的原因是因爲它不實際。計算機世界曾經是基於9位的字節36位字或雙字,一切都是八進制的人以3位爲單位思考,不像我們現在通常以四位,十六進制爲單位。 x86和其他類似的舊體系結構將會執行4位數學運算,BCD和4位進位位等。它只是不實際。世界真的不是以字節爲基礎的,或者是最經常看到的最小內存單元是64位寬,有時是32位。字節是大部分的錯覺... –

+0

您正在使用64或32位寄存器和數據總線,並且無法查看其他24或16位或任何位通道。 C中的位域是1)如此糟糕,你永遠不應該使用它們2)幻象也是如此。它只是創建代碼,你可以寫你的自我,移動和掩蓋,以假裝有一個1位變量的東西。即使C中的字符和短語在我們使用的許多處理器上都是錯覺,比如位字段,它們會創建額外的指令,將較大的寄存器變成更小的寄存器。或相反亦然。 –

回答

4

爲什麼我們沒有4位大小的數據類型?

誰說的? Intel 4004 CPU有4位寄存器和4位存儲器操作數。由於直接支持4位數據類型,因此這種CPU很自然。

Intel 8051 CPU可以直接處理單個位的內存,所以你可以有1位變量。

這些只是CPU的兩個例子,其中數據類型可以非常小,比現在無處不在的8位字節小。

爲什麼我們不能讓他們如果我們這麼傾向?

我們可以。您可以創建一個直接支持4位數據類型的CPU,也可以將4位變量模擬爲較大變量的一部分。

您可以將2個4位變量打包爲8位字節。這種方法的問題是你需要使用更多的指令從8位寄存器或存儲單元中提取4位(你需要一個移位和掩碼(AND)指令),同樣你需要更多指令來正確保存4位位值轉換爲8位字節的一半(加載8位,清除4位二分之一的舊值(帶掩碼/ AND),轉換新值,將其與其餘值組合並保存)。顯然,這會對你的程序代碼大小和速度產生負面影響。此外,4位變量不是很有用,因爲它們可以保存的信息很少。由於這些原因,對較小類型的模擬不太流行。

我已經看過位字段,但我聽說他們不是可移植的,也許還沒用過?

它們被使用。它們的存在恰恰是因爲在一些(但不是全部)應用程序中它們非常有用。如果你有很多短變量,把它們中的幾個變成一個字節或一個機器字可能是有利的,從而減少了內存浪費。

它們不是完全不可移植的。它們在C和C++中的可移植性有限,因爲語言標準沒有精確定義更大數據類型中位域的位置和佈局。這是爲了讓編譯器編寫者在使用位域時最有效地利用CPU功能而完成的。

6.7.2.1 Structure and union specifiers從1999年C標準的clause 10這樣說:

實現可分配任何可尋址存儲單元,大到足以容納一個位域。如果剩餘足夠的空間,緊接在結構中的另一位字段之後的位字段應被打包到相同單元的相鄰位中。如果剩餘空間不足,則將不適合的位字段放入下一個單元或與相鄰單元重疊是實現定義的。位單元內的位字段的分配順序(從高位到低位或從低位到高位)是實施定義的。未指定可尋址存儲單元的對齊方式。

 

我覺得這是機器如何解釋的位位置的位值的結果。 (big-endian,little-endian)

是的,那是原因的一部分。但這絕對不是專門針對位域的。常規的非比特字段類型也有這個問題。

我們也不能像這樣做比任何原始類型都大的位域。那麼爲什麼這些限制?它可以在組裝中完成嗎?

如果您的C(或C++)編譯器(或解釋器)可以模擬比CPU直接支持的類型更大的類型,那麼您甚至可以擁有256位的位域。但是,如果CPU直接支持的最大類型是32位,這意味着使用更大的類型(不管是否是位域)類似於128位的類型將會產生更多的代碼和某些性能因爲單個CPU指令(或其中的幾個指令)將不能處理這些大數據值。您需要更多指令和更多時間來執行這些額外的指令。

是的,這可以在裝配中完成。只要你願意編寫代碼並使其工作,任何事情都可以在彙編中完成。 :)

+0

非常詳細的解釋。但是,如果我爲4位處理器編寫一些C代碼,那麼編譯器是否會考慮int所擁有的位數,比如使它成爲4?同樣,我可能會問,爲什麼沒有1位數據類型,然後答案不會有太大變化。 – Leonardo

+0

符合標準的編譯器必須至少使用16位長的「int」。它可以提供4位類型作爲實現擴展。由於歷史,兼容性,性能和不太可能採用的原因,沒有標準(並且不僅僅是標準,而且標準也要求標準(例如'uint8_t'是標準的,但是可選的))C中的1位數據類型。 –

3

爲什麼我們沒有4位大小的數據類型?

因爲像x86這樣的現代處理器可以工作的最小數量是8位。

爲什麼我們不能讓他們如果我們這麼傾向?

你可以,但他們會慢得多,因爲你不得不做更多的工作,因爲處理器不支持它。

它可以在裝配中完成嗎?

裝配只是一堆處理器的指令,所以如果你的處理器支持它,你只能有效地完成它。

如果你真的學習數字設計,這很有意義;在那之前,你必須將這些限制視爲理所當然。

+0

很好放!要增加@Mehrdad寫的內容,甚至在現代x86處理器上訪問8位可能比訪問32位慢*取決於地址。這就是爲什麼大多數編譯器將結構體內的字段填充爲4字節對齊的原因。 –

+0

這就解釋了爲什麼'int'顯然是最優選的數據類型,比如增量變量。但後來我想知道爲什麼在我的64位處理器上sizeof(int)= 4'。如果這更「自然」的話,我會預見'8'的結果。 – Leonardo

+0

@Leonardo:遺憾的是向後兼容。將'int'改爲64位會破壞很多代碼,儘管從C的角度來看這是一個非常有效的實現。 – Mehrdad