一.有符號數的加減法
1、符號數與無符號數的人為規定性:
一個數,是有符號數還是無符號數都是人為規定的。進行二進制運算時用無符號數或是補碼運算時,結果都是正確的。
10000100+00001110
若規定為無符號數,即 132+146=146D 。
若規定為符號數,則為-124+14=-110,而[-110]補=10010010。解釋:10000100是 -124的補碼,0001110是14的補碼,在機器中運算后得出的結果是[-110]的補碼。機器中的有符號數的運算一般就是補碼的運算。
2、補碼加減法運算
計算機中,當確定為符號數運算時,
符號數一律用補碼表示,運算時符號位和數字位一起參加運算。同樣,運算結果也用補碼表示。
1)兩符號數相加公式:
[X+Y]補 (MOD2)=[X]補+[Y]補 //MOD2即 mod 2^n,即丟棄符號位的進位(因為符號位參與運算是補碼運算的特點)
2)兩符號數相減公式:
[X-Y]補 (MOD2)= [X]補+[-Y]補
3.例子:
求3CH-90H。
首先3CH=0011 1100,90H=1001 0000
(1)當為有符號數時,顯然這兩個數是某兩個數的補碼。(具體是哪兩個數X Y, 需要自己計算)。運算結果也是補碼,是X-Y的補碼 [X-Y]補。機器只運算到這一步。[X-Y]補 就是運算結果,溢出 進位等標志位也都是這個補碼運算過程的結果,由硬件ALU運算。X-Y並不是機器的運算結果,由[X-Y]補求X-Y是在計算機組成原理中由程序員或者編譯器完成的工作,對於編譯器來說運算結果才是X-Y,編譯器屬於軟件,不屬於硬件機器。
根據微機中有符號數(補碼)的減法公式,[x]補(輸入)-[Y]補(輸入)=[x]補+[-Y]補(求補操作結果)=[X-Y]補(微機運算結果) ,求[-Y]補是關鍵。
[x]補=0011 1100,[Y]補=1001 0000,
[-Y]補=[Y]補的 求補=0110 1111(取反)+1(加一)=0111 0000 //不是[Y]補的補碼!!更不存在什么 -[Y]補 的補碼(不存在-[Y]補這種寫法)
解釋求補操作:
無論-[Y]補的符號位是0還是1。正數也可以有求補操作,只是得到的數不叫補碼,就是為了把減法轉換成加法。求補操作 就是取余(求補)(補碼是人規定的,但是求補是數學定義)。證明[-Y]補=對-[Y]補 求補操作:[0]補=[-x]補+[X]補 。[-x]補和[X]補不是正數和負數的關系!!而是互補關系,算數相反,不是邏輯相反。另外仔細想一下,我們學補碼是為了什么?以前是為了求一個原碼的補碼是什么,因為計算機組成原理中 從編譯器到微機 從微機到編譯器 需要原碼變成補碼 補碼變成原碼,但是在微機原理中,就不需要這一部分了,而是需要 求補操作了。計算機組成原理中,是由y原碼求出來的[-y]補,而微機原理中是 對[y]補 求反操作出來的[-y]補,計算過程都不一樣。計算機組成原理中的過程可以理解 但是不是微機真正的運算過程,這一次學習的微機原理的補碼的加減法才是真的硬件的運算過程!
另外,補充一點,X=[X]補 的補碼,由補碼求原碼時不用按照由原碼求補碼的逆過程(補碼為1000 0000時例外!)。
《微機原理與接口技術》中寫道:“由加法器的原理圖,加法器的方式控制M用於控制加減法,當M=0時進行S=A+B操作,當M=1時進行S=A-B操作。當M=1(減法)時,各個異或門對B的各位進行求反,並將1作為初試進位加入結果,也就是執行對B的求反加1,即求補操作。” 也就是說!無論B是有符號數還是無符號數,無論符號位是0還是1,只要M=1,就統統對B執行求補操作!!!所以,求補操作可以對符號位是0的數執行!
所以,[X-Y]補=0011 1100-1001 0000=0011 1100+0111 0000=ACH
(2)
補碼最大好處就是不管是有符號數還是無符號數都可以用同一套加減法
。系統對有符號數和無符號數的加減法都采用一樣的策略。
無符號加減法不存在溢出問題,只是將進位或借位存儲在CF中。
機器不知道你進行的運算是否有符號,如果你進行的是有符號運算,你需要查看OF,否則不需要。
所以,溢出不溢出,是由程序員判斷的,機器不知道。
不管是有符號數還是無符號數,微機都是按補碼運算,至於是進位還是溢出不僅要看進位標志位,還要看溢出標志位。
只不過在做無符號數運算時程序員不考慮溢出標志位,只考慮進位標志位而已。
比如0111+1101,你說它是無符號數7+13呢,還是有符號數7-3呢?
對微機而言這是一回事!
所以,微機中,無符號數時和有符號數時的運算結果一定是一樣的。
(3)注意這道題和《計算機組成原理》學補碼加減運算時的題目的區別。
例子:X=+0101,Y=-1010,求X-Y。
題目給的X Y,是原碼, 所以已經默認是有符號數,也有判斷是否溢出,所以默認的計算過程也是指機器運算過程。
原碼在機器中 均是以補碼保存和運算的,
[x]補-[Y]補=[x]補+[-Y]補=[X-Y]補,只用到了[x]補+[-Y]補=[X-Y]補
屬於類型:已知X Y,所以先求[X]補, [-Y]補 ,便求得[X-Y]補。然后求X-Y。
也就是說,上一題已知的是[X]補 [Y]補,(機器的)運算結果是[X-Y]補。中間過程沒必要求出X Y是什么數。
本題已知的是X Y,先得出機器的運算結果[X-Y]補,在做編譯器的工作由[X-Y]補 求出X-Y。
二者求[-Y]補的方法不一樣:前者是對[Y]補 求補操作 求得的,后者是由-Y求得。
可以說,后面例子是編譯器和微機共同工作的過程,前面例子只關系微機運算。
----------------------------------------------------------------------------------------
二.那么系統是怎么識別有符號數和無符號數的呢?
(1)CPU只會根據輸入信號進行邏輯運算,在硬件級別是沒有有符號無符號的概念,運算結束會根據運算前的信號和輸出信號來設置一些標志位,是不是有符號由寫程序的人決定,標志位要看你把操作數當有符號還是無符號來選擇,就像內存中的數據,你可以按照需要來解析,原始數據在那里,你要按什么數據格式來解析在於自 己的選擇;
在匯編語言層面,聲明變量的時候,沒有 signed 和 unsignde 之分,匯編器統統將你輸入的整數字面量當作有符號數處理成補碼存入到計算機中,只有這一個標准!;
(2)
計算機對有符號整數的表示只 采取一套編碼方式,不存在正數用原碼,負數用補碼這用兩套編碼之說,大多數計算機內部的有符號整數都是用補碼,就是說無論正負,這個計算機內部只用補碼來 編碼!!!只不過正數和0的補碼跟他原碼在形式上相同,負數的補碼在形式上與其絕對值的原碼取反加一相同。
(3)
有符號數和無符號數在計算機里表示都是一樣的,二進制的補碼形式。
是有符號還是無符號,是編譯器來辨認的。
例如:
unsigned char uch, char ch;
在內存中有個數0b11111111.
把它賦給uch,那么uch就是127
如果賦給ch,那么ch就是-1
---------------------------
《微機原理與接口技術》中寫道:“在微機中,對於定點數存在無符號數和有符號數的概念。無符號數表達的是 大於等於0的數,在機器表示時不需要表示符號的信息。...。在計算機中,常用8位,16位,32位,64位等字節整數倍的位數進行定點數的表示。”也就是說,《計算機組成原理》中的5位 7位等的數,實際上是沒有意義的,當時只是為了理解一些運算概念才出的那些題。
《微機原理與接口技術》中寫道 :“時鍾一圈是12個小時,順時針+1,逆時-1,這樣,在時鍾上-1和+11是一樣的。類似,用8位來表示有符號數,它的一周是2^8=256,所以-1就可以用255(2^8-1)來表示,這就是補碼的含義。
再次強調:微機中有符號數的機器表示是補碼。在微機中,將“求反加1”操作稱為求補操作,又稱為算數求反(在數的前邊加上負號)。補碼具有以下特性:
[-x]補=[x]補的求補 //所以,[-x]補 並不是 -[x]補 的補碼!!//在前面加上負號 就是要求補操作:按位求反加一。
[x+y]補=[x]補+[y]補
[x-y]補=[x]補+[-y]補
有第三個補碼特性可以看出,補碼的減法運算可以變為加法運算。這樣,cpu中就可以用加法器直接實現減法,而不再需要再專門設置實現補碼減法的部件了。”
也就是說,微機原理中的加減運算都是補碼加減運算,和計算機組成原理中的加減運算不一樣了!因為是計算機組成原理,所以包括了微機補碼加減運算和編譯器運兩個工作部分算,而微機原理只有補碼加減運算部分,只是計算機組成原理的運算過程中的一部分了。所以,一定要注意計算機組成原理和微機原理的區別,前者包含后者。