1. 程式人生 > >匯編中的有符號-無符號-溢出-進位

匯編中的有符號-無符號-溢出-進位

asm

什麽是有符號數?什麽是無符號數?什麽是溢出(OF)?什麽是進位(CF)?如何區分有無符號 呢?
有符號數,就是帶符號的數,可以是正數或負數。區分正數或負數時,看這個數的最高位是 否為 1,最高位為 1,說明它是負數。最高為 0 說明它是正數。
例如
一個字節有符號數,表示範圍(-128 ~ 127):
A0 :1010 0000 : -96 最高位為 1,說明是負數 80 :1000 0000 :-128 最高位為 1,說明是負數 5B :0101 1011 : 91 最高位位 0,說明它是正數 09 :0000 1001 : 9 最高位位 0,說明它是正數
兩個字節有符號數,表示範圍(-32768 ~ 32767):
A055: 1010 0000 0101 0101 :-24491 201A: 0010 0000 0001 1010 :8218 35B9: 0011 0101 1011 1001 :13753
最高位為 1,說明是負數 最高為 0,說明它是正數 最高為 0,說明它是正數
現在我們對於有符號數有了了解,那麽無符號數呢? 無符號說明這個數是沒有符號的,那麽它的最高位將會變成有效位。不會再用來檢查是否正 負數。
一個字節無符號數,表示範圍(0~ 256): A0:1010 0000 :160
BE:1011 1110 :190
90:1001 0000 :144
50:0101 0000 :80
兩個字節無符號數,表示範圍(0~ 65536): EA00: 1110 1010 0000 0000 : 59904 8000: 1000 0000 0000 0000 : 32768 0900: 0000 1001 0000 0000 : 2304
0080: 0000 0000 1000 0000 :128
可以發現無符號數就是正數,沒有負數,範圍就非常的大。
現在了解了有符號和無符號數,接下來繼續理解什麽是溢出!
溢出:當有符號位超出它的表示範圍就算溢出。
用個例子來表示(1 個字節加法):
0x80 + 0x9F = 0x(1)1F 最終結果等於 0x1F(31)
上面的例子非常明顯,十六進制0x80是十進制-128, 十六進制0x90是十進制-112 那麽他們 相加結果是應該-240,-240 已經超過 1 個字節有符號數(-128~127)的表示範圍了,結果明

顯是錯誤的。此時我們就可這兩個數相加就算溢出。 再用一例子來表示(1 個字節減法):
0x80 – 0x46 = 0x3A 結果等於 0x3A(58)
明顯結果是錯誤的,十六進制 0x80 是十進制-128,十六進制 0x46 是十進制 70, (-128 )– ( 70 )= -198 結果應該是一個負數,而且這個數明顯已經超過 1 個字節有符號數(-128~127) 的表示範圍了,這也是溢出。

現在大致明白了什麽是溢出,總結一下有這種規律:
當兩個有符號數進行運算時,符號位不同時,相加或相減不可能溢出。
只有在符號位相同情況,進行運算下才會溢出。
什麽是進位? 對於進位來說,在無符號進行運算時才會產生進位(加法)或者借位(減法)。
舉個例子(1 個字節):
0xEA +0x55 = 0x(1)3F 結果大於無符號(0-256)所能容納的範圍,產生進位(CF=1)。 0x10 – 0x14= 0xFC 結果由於被減數小於減數,此時就會產生借位(CF=1)
到此我們應該能理解什麽是溢出?什麽是進位(借位)?
但是可能會有人問,那我在匯編中計算一個值,我怎麽知道它是有符號,還是無符號,有該 怎麽去區分呢?
答案是:沒有區分,或者說你當它有符號可以,無符號也可以。 在看一個例子:
0x80 + 0x8F = 0x(1)0F
這個例子中相加後結果即產生了進位,又產生了溢出。
CF =1 ,OF =1;
所以 CPU 不區分有符號或者無符號,它在計算時都當成有符號進行計算,根據結果設置標 誌位。
區分有符號,或無符號是匯編指令。或者說是你決定的。
C 中有 unsigned 與 signed 來確定有無符號。
匯編中有寫指令區分有無符號。

匯編中的有符號-無符號-溢出-進位