[英]Why does CMP (compare) sometimes sets a Carry Flag in 8086 assembly?
我一直在閱讀並使用8086指令集,它說CMP(比較)可以設置進位標志。 我知道比較會減去兩個操作數,但我想知道是否有人可以在這種情況下提供一個例子。
我只是無法掌握添加數字和負數的想法會設置進位標志。 我已經閱讀了借旗,但我只需要一個例子來澄清我對比較指令的理解。
另外,據我所知,如果3 - 5 = -2會設置負標志...何時進位?
通常在使用無符號算術時設置進位標志。 例如,添加兩個無符號(其結果不適合寄存器)數字不會引發溢出標志但只攜帶標志。 但是,使用帶符號算術時,會在這種情況下設置溢出標志。
您可以在此相關問題的答案中找到有關何時將進位和溢出標志設置為0和1的示例,其中加上或減去整數。
你也可以找到樣本C代碼,用8位數字的借位指令模擬帶有進位和減法的加法,你可以使用它,也許可以得到更多的例子。
輸出格式有這樣的:
127( 127) - 255( -1) - 1 = 127( 127) CY=1 OV=0
其中每個數字都表示為無符號和帶括號的括號(2的補碼)。 =
之前的數字是ADC / SBB之前的進位標志。 CY=
和OV=
顯示ADC / SBB后的進位和溢出標志。
比較與沒有借位的減法幾乎完全相同,除了它只影響進位,溢出,符號和零標志(以及奇偶校驗和輔助進位,但它們在這里不重要)而不修改寄存器/存儲器中的任何數字。
https://www.hellboundhackers.org/articles/read-article.php?article_id=729
就像快速總結一樣,我寫這篇文章有兩個目的。 首先,它很有趣,而且對計算機工作原理的更多了解總是有幫助的。 其次,總會有程序直接操作標志,並且知道它們對跳躍的影響是有幫助的。 例如,一些像CMP eax,ebx JC這樣簡單的東西可能會混淆大多數開始的反向器,但希望不會在本文之后。 請享用 :)
[重要說明:當我寫出二進制數字時,我將使用8位整數作為我的例子。 請記住,盡管編程中不常用8位整數,但我討論的相同規則適用於具有更多位的整數]
CMP指令:
CMP指令通過執行兩個操作數的隱含減法來操作。 這意味着結果不會存儲在內存中。 減去它們之后,它會做一些快速測試,更新Z,O,C,S和P標志。 P或奇偶校驗標志很少使用,因此為了簡潔起見,我們將在本文中忽略它。
通過從第一個操作數添加第二個操作數的否定版本來執行二進制減法。 這就像你在中學學到的那樣,關於4 + 3 = 4 - ( - 3),反之亦然。 在文章的最后,我將解釋這是如何完成的,但我現在將轉向更重要的事項,因為破解或編碼並不真正需要這些知識。
標志和零旗:
CMP指令可以設置的四個標志--Z,O,C和S分別稱為零,溢出,進位和符號標志。 只要減法的結果等於零,就設置零標志。 當然,這僅在操作數相等時才會發生。 當減法的結果為負時,設置符號標志。 雖然我們傾向於認為這意味着符號標志與零標志組合足以測試所有>> = <和<=,但事實並非如此,因為即使第一個數字大於第二。 這是因為溢出。
溢出標志:
有符號整數用二進制表示,其位數與無符號整數相同。 當然,這意味着必須在整數的一個位中設置符號。 有符號整數將符號存儲在MSB中(最重要的位)。 這意味着,當00000001以十進制轉換為1時,10000001轉換為-127。 我將在文章中討論為什么它是-127而不是-1或-2。 當處理器執行減法時,如果減法低於00000000或高於11111111,它會回繞。因此,如果從正數中減去負數,或從負數中減去正數,則答案可能會溢出邊界。 例如,100 - (-100)等於200,但8位有符號整數的最高值可以是127,因此200將通過上邊界並最終作為負數,即使它應該是正數。 -100 - 100會出現同樣的問題; 當它應該為負時,它會穿過低端並最終為正,導致下溢。 請注意,下溢也設置溢出標志,溢出將引用文章中的進一步溢出和下溢。 CPU檢查這一點,並設置溢出標志(如果發生)。
攜帶旗幟:
如果兩個操作數都被解釋為無符號整數,則第一個更大時設置進位標志。 這很容易確定,因為每當減法通過00000000進入更高范圍(11111111)時就會發生這種情況。 例如,00000001 - 00000010 = 11111111,因此設置了進位。 但是,00000010 - 00000001 = 00000001,因此未設置進位。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.