以下示例應同時設定進位和溢位標志:
mov eax, -120
add al, 140
add al, 140將類似于以下操作:
10001000
10001100
---------
= 100010100
所以結果有 9 位,而可以放入的最大位數al是 8。但我理解overflow-flag它的方式只有在操作結果“錯誤”時才設定。例如,當將一個正數添加到一個正數時,然后sign-flag設定它會產生一個負數結果。
關于我到目前為止所做的示例中的進位標志,我只在我從一個較大的值中減去一個較小的值時設定它。
所以我的問題歸結為當操作的大小不能在暫存器中表示時進位和溢位標志的行為。
uj5u.com熱心網友回復:
好的,您在這里遇到的問題是與計算機資料型別的作業方式和您正在做的事情不匹配。
一般來說,計算機可以使用(即添加)有符號資料型別或無符號資料型別——但要求它將有符號值添加到無符號值可能會出現問題。
在這里,-120 是負數,所以必須使用有符號表示。
但是,140 本身不適合 8 位有符號,因此在 8 位中,必須使用無符號表示。
硬體不支持這種組合——雖然加法會產生截斷的結果,但如果您執行 8 位加法,硬體不會在標志中為您提供有意義的資訊。
(如果兩個運算元都是 8 位有符號的,或者如果兩個運算元都是 8 位無符號的,則 8 位加法的標志是有意義的,但在混合兩種資料型別時它們并不總是有意義的:特別是當所涉及的值是足夠大,以至于使用高位,例如 -120 有符號 8 位和 140無符號 8 位的情況)
在這里獲得正確結果的方法是將兩個數字轉換為更大的資料大小以容納這兩個數字(它將是一個有符號資料型別,因此它可以容納 -120,當然,轉換方法會有所不同兩個運算元,因為它們是不同的資料型別)。
因此,通過符號擴展將 -120 從 8 位轉換為 16 位(或更大)。
并且,通過零擴展將 140 從 8 位轉換為 16 位(或更大)。
然后,您可以執行加法并獲得帶符號的結果,并帶有有意義的溢位標志。當然,特定的計算不會在 16 位中溢位——事實上,以兩個 8 位值開始的 16 位加法不會溢位。
但是,如果您想將其恢復為 8 位,您可以檢查它是否適合該大小和資料型別。出于所有實際目的,在這種情況下,16 位結果的高 8 位包含與低 8 位結果相關的溢位資訊,而不是標志中的資訊(溢位/進位)。
首先,決定要檢查哪種 8 位資料型別:有符號或無符號。有幾種可行的方法,但一種簡單的方法是將 16 位值截斷為 8 位,然后將其從 8 擴展回 16,然后查看新擴展的 16 是否等于原始 16 位結果。
對于帶符號的 8 位,您會將 16 位結果截斷為 8 位,然后將其符號擴展回 16 位,然后與原始 16 位值進行比較。如果它不同,則該值不適合 8 位有符號。
與無符號 8 位相同:將 16 位結果截斷為 8 位并將其零擴展回 16 位以與原始結果進行比較,如果比較不相等,則它不適合 8 位無符號。
或者,從 16 位原始結果中,您可以檢查低 8 位值的符號位和高 8 位值。如果所有高位與低 8 位的符號位的位值相同,則 16 位結果將適合 8 位有符號而不會丟失。
對于無符號,如果高 8 位為 0,則低 8 位將適合 8 位無符號而不會丟失。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/457483.html
