《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 嵌入式技術(shù) > 解決方案 > 計(jì)算機(jī)系統(tǒng)原理(五) 信息的存儲與值的計(jì)算

計(jì)算機(jī)系統(tǒng)原理(五) 信息的存儲與值的計(jì)算

2017-06-22
關(guān)鍵詞: 匯編語言

上一章(1.1-1.4)LZ和各位簡單的探討了一下計(jì)算機(jī)系統(tǒng)中的一些基本概念,本次我們將進(jìn)入一個(gè)嶄新的世界。在1.1那一章當(dāng)中,我們已經(jīng)簡單的提及了信息的概念,本次我們會逐漸深入的討論信息的相關(guān)內(nèi)容。

引言

我們很難想象,1和0這兩個(gè)再簡單不過的數(shù)字,給計(jì)算機(jī)科學(xué)帶來了徹底的改變。對于無法與人腦相比的計(jì)算機(jī)來說,簡單的1和0就是最適合它們的數(shù)字。不過1個(gè)1或者1個(gè)0往往代表不了任何意義,它們必須被賦予上下文,才能有具體的含義。比如,如果我們知道1和0是代表的布爾類型的值,那么我們就知道1是true,0是false。

對于二進(jìn)制所表示的數(shù)字來說,主要有三種,即無符號、補(bǔ)碼以及浮點(diǎn)數(shù)。

由于計(jì)算機(jī)對于固定類型的二進(jìn)制數(shù)字往往都是有位數(shù)限制的,比如int類型使用四個(gè)字節(jié)(32位二進(jìn)制)來表示,因此在計(jì)算的時(shí)候,會發(fā)生溢出的情況,最簡單的我們使用無符號整數(shù)0xFFFFFFFF與無符號整數(shù)0xFFFFFFFF相乘,則會產(chǎn)生溢出。

在產(chǎn)生溢出的時(shí)候,得出的結(jié)果往往會令人大跌眼鏡。比如兩個(gè)正數(shù)相乘可能得到負(fù)值,兩個(gè)正數(shù)相加也可能得到負(fù)值。而對于不同的計(jì)算機(jī)來說,由于數(shù)值范圍可能有所不同,因此掌握信息相關(guān)的內(nèi)容對于寫出跨平臺的程序來講也是很有幫助的。

信息的存儲

大多數(shù)計(jì)算機(jī)使用8位的塊,或者說字節(jié),來作為最小的可尋址的存儲器單位,而不是在存儲器中訪問單獨(dú)的位。換句話說,我們在訪問存儲器的內(nèi)容時(shí),最小的訪問單位一般是字節(jié)。

在我們編程的時(shí)候,往往會把虛擬存儲器(virtual memory)抽象為一個(gè)字節(jié)數(shù)組,而每一個(gè)數(shù)組內(nèi)的元素或者說字節(jié)都有唯一的地址(address),這些地址的集合就被稱作虛擬地址空間。虛擬地址空間是為了給機(jī)器級的程序一個(gè)概念上的映像,實(shí)際上為了提供這個(gè)映像,內(nèi)部的實(shí)現(xiàn)是非常復(fù)雜的。

十六進(jìn)制表示法

對于機(jī)器來說,可能比較喜歡0和1,但是對于人類這種高級生物來說,1和0就有點(diǎn)不夠看了。因此通常情況下,為了便于閱讀,我們會使用十六進(jìn)制去表示二進(jìn)制。1位十六進(jìn)制的數(shù)字可以表示4位二進(jìn)制數(shù)字,因此一個(gè)字節(jié)就可以表示為0x00---0xFF。

有關(guān)十六進(jìn)制、二進(jìn)制以及十進(jìn)制的轉(zhuǎn)換,LZ這里就直接略過了,相信大部分人應(yīng)該都對這個(gè)轉(zhuǎn)換并不陌生。

每臺計(jì)算機(jī)都有一個(gè)字長(word size),用于指明整數(shù)和指針數(shù)據(jù)的標(biāo)準(zhǔn)大小(nominal size)。而由于虛擬地址空間中的地址就是使用一個(gè)字來表示的,因此操作系統(tǒng)中的字長就決定了虛擬地址空間的大小。

比如32位操作系統(tǒng)下,最大內(nèi)存就是232 = 4 * 210 * 210 * 210 B = 4GB,而在64位操作系統(tǒng)下,LZ還專門問了問群里的猿友,最終得到的結(jié)果是234GB。

數(shù)據(jù)大小

由于計(jì)算機(jī)位數(shù)的不同,會造成在數(shù)據(jù)類型的存儲上,采用的位數(shù)略有不同,下表是在32位和64位機(jī)器下,C語言當(dāng)中的數(shù)字?jǐn)?shù)據(jù)類型需要的位數(shù)。


可以看出,對于長整形以及字符指針類型來說,在32位和64位系統(tǒng)下的字節(jié)數(shù)是不同的。特別的,對于指針類型來說,所有指針類型在32位下都是4位,而在64位下都是8位,這是由虛擬地址空間的地址位數(shù)或者說字長所決定的。

尋址和字節(jié)順序

對于跨越多個(gè)字節(jié)的程序?qū)ο螅ǔ绦驅(qū)ο笾钢噶睢?shù)據(jù)或者控制信息等,是程序當(dāng)中對象的統(tǒng)稱)來說,我們需要制定兩個(gè)規(guī)則,才能唯一確定一個(gè)程序?qū)ο蟮闹怠?/p>

比如對于int類型的值0xFF來說,如果我們要根據(jù)虛擬內(nèi)存地址去獲取這個(gè)整數(shù)值,那么首先我們需要知道它的起始虛擬內(nèi)存地址是多少。另外,我們還需要知道,對于表示int類型的四個(gè)字節(jié)來說,這四個(gè)字節(jié)的排列順序。

對于第一個(gè)問題,由于大部分計(jì)算機(jī)都采用連續(xù)的內(nèi)存地址去存儲一個(gè)程序?qū)ο螅虼宋覀兎Q內(nèi)存地址中最小的那個(gè)就是該程序?qū)ο蟮钠鹗嫉刂罚彩窃摮绦驅(qū)ο蟮牡刂贰?/p>

對于第二個(gè)問題,一般有兩種方式,即大端法和小端法。對于一個(gè)整數(shù)0x000000FF來說,我們假設(shè)它的起始地址為0x1,那么對于使用大端法規(guī)則的系統(tǒng)來說,0x1-0x4的虛擬內(nèi)存所存儲的值依次為0x00、0x00、0x00、0xFF,相反對于采用小端法規(guī)則的系統(tǒng)來說,0x1-0x4的虛擬內(nèi)存所存儲的值依次為0xFF、0x00、0x00、0x00。

強(qiáng)制類型轉(zhuǎn)換

對于一個(gè)特定的數(shù)據(jù)類型來講,計(jì)算機(jī)在解釋這類數(shù)據(jù)的值的時(shí)候,是根據(jù)起始位置以及數(shù)據(jù)類型的位數(shù)來確定的。比如對于無符號int類型的數(shù)據(jù)來說,倘若我們知道它的起始位置為0x1,而當(dāng)前的操作系統(tǒng)采取的是大端法規(guī)則,假設(shè)0x1-0x4的內(nèi)存地址中存儲的字節(jié)依次為0xFF,0xFF,0xFF,0xFF,由此計(jì)算機(jī)將會幫我們計(jì)算出這個(gè)無符號int類型的值為232-1,也就是無符號int類型的最大值。

這其中計(jì)算機(jī)是根據(jù)0x1-0x4這四個(gè)字節(jié)上的值,以及無符號int類型的解釋方式,最終得到的這個(gè)無符號int類型的值。

由此可見,計(jì)算機(jī)在解釋一個(gè)數(shù)據(jù)類型的值時(shí)主要有四個(gè)因素:位排列規(guī)則(大端或者小端)、起始位置、數(shù)據(jù)類型的字節(jié)數(shù)、數(shù)據(jù)類型的解釋方式。

對于特定的系統(tǒng)來說,前兩種因素都是特定的,而對于后兩種因素的改變,則可以改變一個(gè)數(shù)據(jù)類型的值的最終計(jì)算結(jié)果,這就是強(qiáng)制類型轉(zhuǎn)換。對于大部分高級程序設(shè)計(jì)語言來講,都提供了強(qiáng)制類型轉(zhuǎn)換。

比如C語言,我們可以將一個(gè)無符號int類型的值強(qiáng)制轉(zhuǎn)換為其它類型,在轉(zhuǎn)換之后,對于上面四個(gè)因素之中,改變的是最后兩個(gè)。為此我們寫一個(gè)小程序來看下這個(gè)有意思的事情。

#include <stdio.h>
   
int main(){
   unsigned int x = 0xFFFFFF61;
   int *p = &x;
   char *cp = (char *)p;
   printf("%c\n",*cp);
}

這是一個(gè)簡單的強(qiáng)制類型轉(zhuǎn)換示例,可以看到我們將一個(gè)無符號int類型的值,先賦給了一個(gè)int類型的指針,又強(qiáng)制轉(zhuǎn)換成了char類型的指針,最終我們輸出這個(gè)char類型指針?biāo)淼淖址Y(jié)果的輸出是一個(gè)a。

輸出a的原因就是由上面的四個(gè)因素決定的,我們看這個(gè)具體程序上的四個(gè)因素。

1、cp指針的值與x變量的起始內(nèi)存地址相等。(起始位置)

2、LZ的linux系統(tǒng)是小端表示法,也就是說假設(shè)x變量的起始內(nèi)存地址為0x1,那么0x1-0x4的值分別為0x61、0xFF、0xFF、0xFF。(位排列規(guī)則)

3、char只占一個(gè)字節(jié),因此會只讀取0x61這個(gè)值。(數(shù)據(jù)類型的字節(jié)數(shù),或者說大小)

4、0x61為十進(jìn)制的97,對應(yīng)ascii表的話,代表的是字符a,因此最終輸出了a。(數(shù)據(jù)類型的解釋方式)

可以看出,強(qiáng)制類型轉(zhuǎn)換有時(shí)候會讓結(jié)果變的讓人難以預(yù)料,因此這種技巧一般不太推薦使用,但是這種手段也確實(shí)是程序設(shè)計(jì)語言所必需的。

字符串的表示

這一點(diǎn)其實(shí)上面我們已經(jīng)提到了,我們知道97其實(shí)代表的是字符'a',而這個(gè)的由來就是根據(jù)ascii表來的,我們在linux系統(tǒng)上可以輸入man ascii命令來查看。

代碼的表示

二進(jìn)制如何表示代碼?

其實(shí)這些都是編譯器的責(zé)任了,我們只需要寫出像上面那個(gè)小程序一樣的人們可以看懂的代碼,編譯器便會幫我們將其翻譯成對應(yīng)的機(jī)器所認(rèn)識的二進(jìn)制序列。從這個(gè)角度上來講,程序語言其實(shí)就是一個(gè)二進(jìn)制序列的簡單描述,它提供我們更簡單的編寫計(jì)算機(jī)可以執(zhí)行的二進(jìn)制序列的方式。

文章小結(jié)

本次我們初步探索了信息的存儲以及信息所代表的結(jié)果的計(jì)算,這些內(nèi)容都比較基礎(chǔ),相信不難看懂。


本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點(diǎn)。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問題,請及時(shí)通過電子郵件或電話通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話:010-82306118;郵箱:[email protected]