進位與溢位旗標
你在紙上加兩個數,答案衝出你畫的格子右邊時,你會皺眉發現。處理器也有同樣的麻煩——它的字組是固定寬度——所以 ALU 在每個結果旁邊都點亮幾盞一位元的警示燈,稱為條件旗標。最重要的四盞是零旗標(結果全為零)、負旗標(最高位元即符號位元為 1)、進位旗標(最高欄產生了進位輸出)、溢位旗標(有號答案因放不下而出錯)。它們很小,卻承載著算術是否真的成立的真相。
進位與溢位聽起來相似,回答的卻是不同問題,把它們搞混是經典的新手錯誤。進位旗標關乎無號算術:當最高欄產生進位輸出時被設定,意味著真正的無號和需要比字組多一個位元。溢位旗標關乎有號(二補數)算術:當兩個同號數產生相反號的結果時被設定,而這只可能在真正答案超出有號範圍時發生。判斷溢位有個漂亮的規則:當「進入符號位元的進位」與「離開符號位元的進位」不同時,就發生溢位。同一次加法可能設進位、設溢位、兩者都設或都不設,取決於你選擇怎麼解讀這些位元。
這些旗標存在是為了讓軟體能據以反應。在一次比較之後(比較其實就是把結果丟掉、只留下旗標的減法),條件分支看旗標決定往哪走:相等則分支測零旗標,小於則分支測負旗標與溢位旗標的組合。誠實的重點是:硬體把兩種解讀都回報出來,拒絕替你猜是哪種——透過你測哪個旗標,由你的程式來宣告這些位元是有號還是無號。
在 8 位元有號運算中,加 100 + 50。真正答案 150 超過有號上限 127,位元出來是負 106,溢位旗標被設定(兩個正數給出負數)。把同樣位元當無號讀則沒有進位輸出,所以進位旗標保持 0。
進位看的是無號範圍;溢位看的是有號範圍。同樣的位元,兩種裁決。
進位不是溢位。進位輸出只對無號數有意義;溢位只對有號數有意義。一次正確的無號加法也可能把溢位旗標設起來,硬體並不在意——由你的程式選擇哪個旗標才相關。