這個問題並不難,簡單點的說就是邏輯運算啦。邏輯運算是CPU運算的本質,學過數學或者計算機的人都很容易理解的。再複雜的運算都是由這些最基本的邏輯運算構成的。接下來讓我們詳細的了解一下吧。
邏輯運算是CPU運算的本質,不管是計算機能處理多麼複雜的事情,它最終還是通過電路的開關來實現的。邏輯是指對某個事物的推理,「真」和「假」是兩個對立的邏輯狀態,邏輯運算是指用數學符號來表示邏輯狀態,以便於用數學方法研究邏輯問題。我們通常將電路通電狀態表示為「真」,用數字「1」表示,不通電錶示為「假」,用數字「0」表示。「或」、「與」、「非」是三種基本邏輯運算,計算機邏輯運算也包含「異或」、「位」。
1、或運算
或運算:彙編中用「OR」表示,C語言中用「|」來表示,可以理解為「或者」,即只要有一個條件滿足就為「真」,用電路來描述:只要有一條電路通電這條總電路就能通電,原理如圖1-6-1:
這是一個並聯電路圖,不管是A為閉合狀態、還是B為閉合狀態,還是AB都處於閉合狀態,電燈泡都能亮。我們把電路圖用符號0和1來表示,或運算表示只要有一個為1,結果就為1。我們來看一個寬度為8的或運算:
2、與運算
與運算:彙編中用「and」表示,C語言中用「&」來表示,它表示兩個條件都成立才能為真,即兩個都為1結果為1,其他為0,電路實現原理如圖1-6-2:
這是一個串聯電路圖, A和B都為閉合狀態,燈泡才能亮。如果有一個開關沒有閉合,燈泡是不能亮的。即兩個都為1,結果為1,只要有一個為0 ,結果為0。
我們來看一下下面的運算:
3、異或
異或:彙編用「xor」表示,C語言中用「^」表示,這個不是太好理解,但是它很有用。它表示兩個值不同為真,相同為假。即兩個值如果都為0或者1,結果為0。一個為0,而另一個為1,結果為1。如圖1-6-3所示:
這條電路A和B必須是相反的兩種狀態燈泡才能亮,如果AB都斷開,燈泡無疑是不亮的,如果AB都連上,正負極抵消,燈泡同樣不能亮。我們來看一下下面的運算:
4、非運算
非運算:彙編中用「NOT」表示,C語言中用「!」表示,它是對某個值求反的運算。如 !0 = 1;!1 = 0;非真即為假,非假即為真。
我們來看一下下面的運算:
5、左移運算
左移運算:在右邊添0,數據往左移動,用符號「<<」表示,如「0010 << 1 」表示將0010左移1位,結果為0100。
6、右移運算
右移運算:在左邊添0,數據往右移動,用符號「>>」表示,如「0010 >> 1」表示將0010右移1位,結果為0001。
【邏輯運算的具體應用】
例1:計算機通過邏輯運算實現四則運算。
計算機的本質是邏輯運算,不管多麼複雜的運算最終都回歸到邏輯運算。可是我們生活當中的計算並不是邏輯運算,這又是怎麼回事呢?那麼CPU是如何通過邏輯運算做「+、-、*、/」的呢?雖然我們平常生活中並不會碰到這個問題,但是可以做一些簡單的了解,能幫助我們更清楚地認識計算機的本質。
我們來看一下CPU是如何算出2+3等於5的。
計算機如果要做運算,必須要把2和3分別存儲下來,就是先用幾條線路來表示它們。前面我們學數據寬度時講到容器,那我們就用最少的容器來保存2和3。假設有BYTE x保存2,BYTE y 保存3,那這兩個容器裡的數值是這樣的:
這個結果放在哪呢?我們再拿一個容器R來保存,假設它的寬度也是8位,此時R的值為:0000 0001。
第二步,CPU再讓它們進行與運算:
這一步是為了測試上一步有沒有結束。
再將這個結果左移1位,如果這個值等於0,那R就是計算的結果,不為0重複之前的操作。0000 0010左移1位等於0000 0100,不為0,所以繼續運算, 將R容器裡的值放到x容器中,把與(and)的值放在y裡,
x: 0000 0001
y: 0000 0100
繼續之前的操作,先將它們異或,值為0000 0101,將這個值存到R容器。再將x容器和y容器裡的與運算,值為0000 0000。將它左移一位還是0,所以R的值就是我們計算的結果,即為0000 0101,轉換為十進位就是5。
2+3對於我們來說,幼兒園就會算了,而計算機卻要執行如此多步驟。其實計算機很笨,它只會按照一定規則去操作,但是它卻靠著比我們人類快無數倍的速度幫我們人類解決很多棘手的問題。
例2:獲取某個數的第N位的值。
比如我們的寄存器每一位代表不同的含義,假如需要判斷某一位的值,或者更改某一位的值、而其他的值保持不變,那怎麼才能做到呢?如有個數值,我想知道它的第3位是否為1,應該怎麼運算呢?根據前面的邏輯運算,我們知道與運算的法則是「有0為0,兩個都為1才為1」,所以我們可以設置一個第3位為1的值,無論我們要測試的值是幾位數,我們只需要將它與0100進行與運算即可。當這個值與「0100」進行與運算,只能是兩個結果,一個結果為0,一個結果為 0100,也就是結果只有兩種情況:「0」和「非0」,若為0,這個數值的第3位為0,反之,不為零。
所以我們可以利用與、或的特點,我們來驗證一下,假設有個要測試的值為8F,我們要測試它的第5位是否為0。
根據之前的方法,我們將它和「0001 0000」相與:
結果為0,所以這個值的第5位也是0。
例3:加密解密
異或在加密算法裡經常遇到,兩次異或同一個值,就會還原成異或原來的值。這個需要異或的值我們叫做密鑰。採用異或加密的時候,密鑰的作用很關鍵。諜戰片裡的那些電報也是加密的,常常因為一本密碼本劇情起伏不斷,可見密鑰的重要性。
比如我們要加密0x2015,密鑰為:0x54計算如下:
加密:每兩位十六進位數分別與54進行異或: