C++/Debug模式查看EFL(標誌寄存器)詳解

在好比使用匯編指令如:ADC, SBB等指令時,咱們爲了內心那份好奇感就不得不去了解下FLAG寄存器(EFL)裏面的東西。經過二進制詳細的查看各標誌位的值。而後這些須要用到標誌寄存器的指令等就一目瞭然了。 - -ios

火燒眉毛寫了段測試代碼來看看其中的祕密:測試

#include <iostream>.net

int main( void )
{
    __asm
    {
        mov al, 0xff
        mov dl, 0x01調試

        add al, dl
        adc al, dl
    }blog

    return 0;io

}asm

仍是用內斂彙編的形式來講明。 這裏想AL給了一個0xff,爲何給AL爲0xff是爲了可以進位,我以爲這個數很方便,固然你能夠弄成其它數字,只要兩個數之和發生進位就行(這裏爲了測試進位的CF位)。DL我給了個0x01之和恰好進位且能夠測試奇偶和零值。stream

咱們在上邊紅色的代碼出打下斷點,而後運行程序斷到這裏,而後打開VC的寄存器窗口,咱們能夠看到各個寄存器的值。這裏着重看EFL = ? 標誌寄存器的值。二進制

這裏查看標誌寄存器各標誌位的值有兩種查看方法:請求

第一: 把EFL的值轉成二進制,經過二進制位來查看個標誌位的值。

第二: 若是你的寄存器窗口裏面沒有顯示標誌的話,能夠在寄存器窗口裏麪點鼠標右鍵,選擇「標誌」就會顯示個標誌位的值了,形如:

OV = ? UP = ? EI = ? PL = ? ZR = ? AC = ? PE = ? CY = ?

這裏有個對照表:

 

 asm

 

能夠根據EFL的二進制數據進行位對照就知道各個標誌位的值了。

咱們在開始的斷點那裏看到標誌的各值:

OV = 0 UP = 0 EI = 1 PL = 0 ZR = 0 AC = 0 PE = 0 CY = 0

這裏EI = 1表示處於中斷狀態  - -。。

再看EFL = 0x00000202(1000000010) 對號入座:

1    0   0   0   0   0    0    0    1    0

IF  TF  SF ZF      AF         PF        CF  

只有IF(EI|DI)爲1, VC寄存器窗口裏邊只用括號中的一種來表示。。。

好!看完了各標誌位,下面按F10執行完ADD AL, DL這句。

看看各標誌位的值:OV = 0 UP = 0 EI = 1 PL = 0 ZR = 1 AC = 1 PE = 1 CY = 1

再來看看標誌寄存器的值: EFL = 0x00000257(1001010111)

1    0    0    1   0   1   0   1   1   1

IF  TF   SF  ZF      AF       PF      CF

這裏IF表示已經中斷, ZF表示目的操做數結果爲零, AF表示(AL爲一個字節)相加進行到一半(低4位)有沒有向另外一半(高4位)進位,也能夠表示是否借位(減法)。 PF表示爲偶數, CF表示已經發生進位,也能夠表示借位。

再按F10執行完 ADC AL, DL 這句, ADC是帶進位的加法, 結果爲: AL = AL + DL + CF。

這時AL: 0 + 0x1 + 1 = 0x02。

標誌位值: OV = 0 UP = 0 EI = 1 PL = 0 ZR = 0 AC = 0 PE = 0 CY = 0 這裏就不作解釋了吧 - -

這裏特別說下:

DF:是控制標誌位爲方向標誌,在串處理指令中控制處理信息的方向用。當DF爲1時,每次操做後使變址寄存器SI和DI減少,這樣就使串處理從高地址向低地址方向處理。當DF爲0時相反。。

TF:當TF被置爲1時,CPU進入單步執行方式,即每執行一條指令,產生一個單步中斷請求。這種方式主要用於程序的調試。

在這裏咱們要得到標誌寄存器的值的話有如下這些指令:

LAHF     標誌寄存器傳送,把標誌裝入AH.
SAHF     標誌寄存器傳送,把AH內容裝入標誌寄存器.
PUSHF   標誌入棧.
POPF     標誌出棧.
PUSHD  32位標誌入棧.
POPD    32位標誌出棧.

在上邊的AF位讓我想到用ADC或者SBB來進行進位或借位的一個經常使用方法就是,咱們能夠在加/減兩個4字節的數據是能夠高2字節、低2字節分別相加。經過ADC/SBB能夠在計算高2字節想加/減時得到CF值,用來進行進位或借位。

例如:

mov ax, low1

add ax,  low2

mov sumLow, ax

mov ax, high1

adc  ax, high2

mov sumHigh, ax

這樣就實現了進位, low1, low2分別表示第一個數和第二個數的低2字節, high1, high2分別表示第一個數和第二個數的高2字節。 當 add ax,  low2 產生了進位時, CF = 1。 後邊在執行高2字節相加時用ADC會去獲取CF的值。 sumHigh = high1 + high2 + CF。 最後獲得的數就是高2字節之和(sumHigh)與低2字節之和(sumLow)的合併。形如:

DWORD var = 0;

WORD   sumHigh = 0;

WORD   sumLow = 0;

C++:

var |= sumHigh;

var <<= 16;

var |= sumLow;

ASM:

movzx eax, word ptr[ sumHigh ] shl   eax, 10h or    eax, dword ptr[ sumLow ] mov   var, eax

相關文章
相關標籤/搜索