1. 程式人生 > >學習筆記-----淺談彙編指令CMP執行機制

學習筆記-----淺談彙編指令CMP執行機制

在彙編中,CMP和JMP指令常常用於比較操作,而且檢視反彙編原始碼時也發現不管是.IF偽指令還是其他的底層都是用CMP實現的。

指令格式:

CMP 目的運算元,源運算元

計算機在遇到CMP指令的時候,CPU將目的運算元和源運算元做減法(即目的運算元-源運算元)從而根據運算結果修改標誌位(如OF, CF , ZF, SF等)的值,然後接下來用相應的跳轉指令來進行選擇執行哪一段程式碼

另外,運算元有無符號是個頭疼的事情,CPU並不能確定它運算的是有符號的減法還是無符號的減法,所以CPU會產生兩套標誌位。

由於我學的不是很深,下面只是簡單的討論一下CMP指令執行後標誌位的結果(有錯誤請指出)

ZF: 置零標誌位,當結果為0的時候ZF被賦值1

SF:負數標誌位,當結果是負數的時候被賦值1

CF:進位/借位標誌位,當最高位向它的上一位有借位或者進位的時候被賦值1

OF:溢位標誌位,當有益處時(即運算結果超過了它的型別(如BYTE, WORD, DWORD)所能表示的範圍)被賦值1

溢位的說明:兩個正數相加,兩個負數相加,正數減負數,負數減正數  都有可能溢位

      正數溢位變負數,負數溢位變正數

1:無符號數的比較

目的運算元 < 源運算元ZF=0CF=1JB,JNAE

目的運算元 = 源運算元ZF=1CF=0JE,JZ

目的運算元 > 源運算元ZF=0CF=0JA,JNBE

2:有符號數的比較

目的運算元 < 源運算元ZF=0SF=1OF=0JL

ZF=0 SF=0OF=1

目的運算元 > 源運算元ZF=0SF=0OF=0JG

ZF=0 SF=1OF=1

目的運算元 = 源運算元ZF=1JE

另外在之前一直對CMP指令和之後的跳轉指令的順序模糊不清,現在也記錄一下

MOV EAX, 0

CMP EAX, VAL1

JBE FINISH

INC EAX

FINISH:

INC EAX

當比較EAX 和VAL1的值之後,

如果EAX <= VAL1 則跳轉到FINISH將EAX加1,最後EAX=1.

如果EAX > VAL1 則不跳轉 執行inc eax ,此時EAX=1, 隨後CPU並不是跳過FINISH語句塊,而是接著FINISH的語句繼續執行,所以還會執行一個INC EAX,最後EAX=2

想說明的一點就是CPU的指令時按順序一句一句執行的,除非遇到像JMP 或者CALL 之類的語句會實現跳轉。上述例子中EAX > VAL1時沒有實現跳轉,所以依舊是一步一步繼續執行。

所以如果想實現EAX和VAL1比較  大於則將eax賦值1,小於則不變,可以使用短路跳轉法

CMP EAX, VAL1

JBE FINISH

MOV EAX, 1

FINISH:

...........

如果想要用JA的話

CMP EAX, VAL1

JA Larger

JMP FINISH            //此處需要告訴CPU跳過Larger語句 不執行大於時的操作

Larger:

MOV EAX,1

FINISH:

...........

就需要在JA跳轉後直接跳過Larger, 因為如果沒有JMP FINISH語句,當不滿足JA(即EAX > VAL1) CPU會繼續執行後面的語句Larger 所以最後不管EAX和VAL1的大小關係如何

EAX都被賦值1。