這篇文章不是從0開始的,前面還有一些匯編基礎指令以及進制,我都沒寫,時間問題,還是今天空閑,我才想補一下博文,后面我陸續會把前面知識點漸漸補上。我不會重0基礎講起,中間會以、匯編、C、C++交叉的形式講解,實戰或者學習中才能更好的提升自己!
EFLAGS寄存器
這些標記出來的標志位十分重要,如果對於逆向開發,這些是需要課在腦子里的,可以不強背,實戰中運用熟悉就自然記來了,為了方便描述,僅以8位來描述
演示之前,請讀者參照下方紅色字體,進行簡單設置一下,后面都參考該格式。
OD中展示一遍效果,AL是EAX中的低8位(后面有時間這塊我再發博文補充一遍,如果沒有,請讀者自行去學習一下吧,博主剛畢業,時間很有限),為了方便演示,我們直接將鼠標移到EAX,右鍵Modify將其改為0,中間那個框就是標志寄存器,為了演示每次的效果,方便我們觀看標志位發生改變,我們用鼠標雙擊,將其全部改為0;
1、進位標志CF(Carry Flag):如果運算結果的最高位產生了一個進位或借位,那么,其值為1,否則其值為0。
MOV AL,0XFF
ADD AL,0X2
代碼添加紅框所示,按F8,代碼往下走,我們一個一個的看!(這里講解的是Carry flag)所以只看C位!!!
有個疑問?0xFF加上0x2之后,EAX里的值為什么是0x00000001呢?為什么不顯示0x00000101呢?1去哪了呢?
這里1並沒有不存在,而是存在了Carry flag里,我們之前將C為置成了0,相加過后變為了1,最高位發生了進位,C為就變成了1。(讀者也可以去試試借位的情況,博主這里趕時間制作,就不演示了,后面內容還挺多,我想趕在12點前寫完)
2、奇偶標志PF(Parity Flag):奇偶標志PF用於反映運算結果中“1”的個數的奇偶性。如果“1”的個數為偶數,則PF的值為1,否則其值為0。
MOV AL,0X5
ADD AL,0XA
對應的二進制得熟悉啊,不然思考起來很費勁!!!建議熱愛的方向有與匯編相關的,一定要把十進制1 ~ 15對應的十六進制背下來啊
0x5 加上0xA,很顯然為0xF,對應的二進制位1111,1的個數為4個,是偶數個,所以Parity flag為1(大家可以試試奇數個的情況,其實我代碼里已經有了奇數個的,不知道大家有沒有管擦到~~~)
3、輔助進位標志AF(Auxiliary Carry Flag):
在發生下列情況時,輔助進位標志AF的值被置為1,否則其值為0:
(1)、在字(word)操作時,發生低字節向高字節進位或借位時;
(2)、在字節(byte)操作時,發生低4位向高4位進位或借位時。
MOV EAX,0X555EFFFF MOV AX,0X5EFF MOV AL,0X5F
ADD EAX,0X2 MOV AX,0X2 MOV AL,0X2
4、零標志ZF(Zero Flag):零標志ZF用來反映運算結果是否為0。
如果運算結果為0,則其值為1,否則其值為0。在判斷運算結果是否為0時,可使用此標志位。
XOR EAX,EAX
MOV EAX,2
SUB EAX,2
我們先演示XOR(異或),這里我們需要先修改EAX里的值為AAA,當然了,既然是異或,那隨您意了,隨便什么數都行
5、符號標志SF(Sign Flag):符號標志SF用來反映運算結果的符號位,它與運算結果的最高位相同。
這里,請讀者拋棄掉以前課本上或者網絡上有關描述最高位為1代表負數的觀念(后續我會單獨出博文,描述有符號數,無符號數),最高位為1代表負數純屬扯淡(如果是這樣,計算機存的最大數豈不是要砍半,計算機發明的豈不是太low了),讀者先記住一個觀念有符號數,無符號數純屬編碼者決定,跟計算機沒關系!!!不然我后面講不下去。。。。。
Sign Flag僅僅用來反映運算結果最高位是1,還是0,不代表有符號數,無符號數~~~
6、溢出標志OF(Overflow Flag):溢出標志OF用於反映有符號數加減運算所得結果是否溢出。
如果運算結果超過當前運算位數所能表示的范圍,則稱為溢出,OF的值被置為1,否則,OF的值被清為0。
最高位進位與溢出的區別:
進位標志表示無符號數運算結果是否超出范圍.
溢出標志表示有符號數運算結果是否超出范圍.
溢出主要是給有符號運算使用的,在有符號的運算中,有如下的規律:
正 + 正 = 正 如果結果是負數,則說明有溢出
負 + 負 = 負 如果結果是正數,則說明有溢出
正 + 負 永遠都不會有溢出.
這個標志位有點不好理解,需要對有符號,無符號數具有很明確的概念,其實理解了很簡單(就類似於很多人不懂自己多少歲一樣,過了18歲生日,還以為自己是18歲,其實已經是19歲了)
這一塊呢,可以參考一下Carry Flag標志位來理解,因為C為僅僅表示最高位有沒有發生進位
a、無符號、有符號都不溢出
MOV AL,0X8
ADD AL,0X8
b、無符號溢出、有符號不溢出
c、無符號不溢出、有符號溢出
d、無符號、有符號都溢出
為什么這個說有符號、無符號都會溢出呢?
首先從無符號角度來看,0xFF,僅僅只代表8位能存的最大正數(255),0x80為 128,既然0xFF已經代表8位能存的最大正數了,就算它加1,也必然溢出
從有符號角度來看,0xFF,代表着 -128,8位中最小負數,0x80代表8位中最大負數 -1,既然0xFF已經代表了8位中能存的最小負數了,它再加 -1 (0x80)豈不是更小了,所以也必然溢出
本文只講述了9個標志寄存器中的6個,因為這6個比較常用,也是博主目前知識儲備中需要用到的6個,后面三個日后接觸到,再來補充文章
如果看完本文,您覺得已經掌握了這6個標志寄存器,建議您可以做一做下面的題目,加深對標志寄存器的理解(答案在筆者電腦里,如果有需要,可以留郵箱,筆者私發給你,不難,看完文章就可以做出來)
1、寫匯編指令只影響CF位的值(不能影響其他標志位)
2、寫匯編指令只影響PF位的值(不能影響其他標志位)
3、寫匯編指令只影響AF位的值(不能影響其他標志位)
4、寫匯編指令只影響SF位的值(不能影響其他標志位)
5、寫匯編指令只影響OF位的值(不能影響其他標志位)
第一篇博文發的有點匆促,許多知識點也未曾講述明白,但本文意圖旨在講述EFLAGS寄存器 (標志寄存器),很多附帶的知識點,筆者后面有時間會繼續發出來!
寫博文不容易,一方面是給自己留筆記,另一方面,也希望留給希望學習相關知識的人更清晰的參考,筆者在學習過程中,碰到過很多問題,曾也因為找不到很好解決問題的文章而苦惱過,編程從不是一個看懂聽懂就行的,一定是多加實踐、實踐、實踐、總結、總結、總結出來的,願牛人技術越牛,新人更上一層樓!祝自己祝大家都能成為自己想成為的IT技術大牛!