(反彙編)邏輯語句的純算術實現

    瞄的,IT項目管理再次延期考試,就不能一次給個痛快麼,已經是第二次延期了.瞄的-____-|||

 

    羣裏有人貼了段代碼,覺得比較好玩,就自己看一下(好吧,下面不是想說這段代碼,不過代碼還是可以貼一貼的)

 

    這個有愛的同學自己分析吧,測試一個int裏面是不是含有0的byte.下面入正題,上圖

 

    注意到紅框圈出來的3句彙編麼,這3句彙編是很有來頭d,想深入瞭解的同學可以看看<逆向工程揭祕>的附錄部分.

    上面的彙編是前面代碼的反彙編,前面的hasZeroByte()這個函數返回的是一個bool型,簡單來說,true是1,false是0;一般在彙編的邏輯是cmp怎麼怎麼樣,然後jz哪裏,不然就jmp哪裏來設置返回值(好吧,不要深究這句話,你能意會就OK了),但是這裏確實是用一種所謂的算術方式來實現邏輯語句,簡單的3句彙編就把返回值搞定了.

    下面分析一下,neg指令是彙編裏面的求補,你可以這麼理解:1.按位求反後加1;2.用0減去操作數之後結果返回操作數;兩種理解都對,但是推薦是用第二種理解方式,爲什麼?因爲neg會設置CF位.科普一下,CF位就是所謂的進位/借位標誌,OF是溢出標誌,兩者都可以用來描述操作是否溢出(溢出不一定是上溢,還有下溢),那麼區別在哪裏?CF位用於無符號數當中的溢出置位,OF用於有符號數中的溢出置位.另外,neg在執行的時候,如果操作數爲0,那麼CF位置位0;如果操作數非0,那麼CF位置位1.結合起來,用第二種理解方式是能夠更好的理解的.

    我們知道,函數返回值一般都是通過eax返回的,這個沒有異議,這裏對eax的操作就是對返回值的操作.由於前面的彙編當中一直以eax作爲操作的寄存器,根據代碼,最後要判斷的就是eax != 0,同時eax也是返回值,記得上面說true是1,false是0,好吧,這裏也許有點繞口,如果說eax==0成立,那麼我們返回false,也就是返回0,那就是直接返回eax(因爲他已經是0),如果eax!=0成立,那麼我們返回1.

    看下彙編代碼是如何做的,首先neg eax,我們知道了,他會設置CF位,進而第二句,sbb eax, eax;sbb op1,op2實際執行的就是借位減法,這樣操作,op1-(op2+CF),如果CF被置位爲1了(eax不爲0),那麼經過這次操作之後,eax就是0xffffffff(也就是-1),之後再進行一次neg eax,那麼eax最終就是1了,跟我們上面說的一樣,如果eax不爲0,那麼返回true(就是1);如果CF是置位爲0(也即是eax爲0),那麼sbb eax,eax的結果也是0,最終neg eax仍然是0,也跟我們上面說的一樣,如果eax是0,那麼我們就返回false(就是0);

    這就是所謂的邏輯語言的純算術實現了.利用一些彙編指令的特性得到的一些比較有趣的用法.最後得到的結論是,編譯帝威武..vczh大神威武..

    不知道我講清楚了沒有,大家有興趣做道題吧

--------------------------------------------我是分割線---------------------------------------------------

    答案:

  

 

    如有不對之處,大家一起討論討論^_^

 

    末尾的吐槽:失眠太多不是一個好的症狀,AM I LOST?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章