天天看點

學習筆記-----淺談彙編指令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=0 OF=1

目的操作數 > 源操作數 ZF=0SF=0OF=0JG

ZF=0 SF=1 OF=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。

繼續閱讀