C Debug模式檢視EFL(標誌暫存器)詳解

2021-07-02 02:26:31 字數 2742 閱讀 3793



在比如使用彙編指令如:adc, sbb等指令時,我們為了心裡那份好奇感就不得不去了解下flag暫存器(efl)裡面的東西。通過二進位制詳細的檢視各標誌位的值。然後這些需要用到標誌暫存器的指令等就一目了然了。 - -

迫不及待寫了段測試**來看看其中的秘密:

#include

int main( void )

return 0;

}還是用內斂彙編的形式來說明。 這裡想al給了乙個0xff,為什麼給al為0xff是為了能夠進製,我覺得這個數很方便,當然你可以弄成其它數字,只要兩個數之和發生進製就行(這裡為了測試進製的cf位)。dl我給了個0x01之和剛好進製且可以測試奇偶和零值。

我們在上邊紅色的**出打下斷點,然後執行程式斷到這裡,然後開啟vc的暫存器視窗,我們可以看到各個暫存器的值。這裡著重看efl = ? 標誌暫存器的值。

這裡檢視標誌暫存器各標誌位的值有兩種檢視方法:

第一: 把efl的值轉成二進位制,通過二進位制位來檢視個標誌位的值。

第二: 如果你的暫存器視窗裡面沒有顯示標誌的話,可以在暫存器視窗裡面點滑鼠右鍵,選擇「標誌」就會顯示個標誌位的值了,形如:

ov = ? up = ? ei = ? pl = ? zr = ? ac = ? pe = ? cy = ?

這裡有個對照表:

可以根據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

afpfcf

這裡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

C Debug模式和Release模式的區別

vs中的程式有兩種編譯模式 debug模式和release模式。debug通常稱為除錯版本,通過一系列編譯選項的配合,編譯結果通常包含除錯資訊,而且不做任何優化,以為開發人員提供強大的應用程式除錯能力。release通常稱為發布版本,是為使用者使用的,一般客戶不允許在發布版本上進行除錯,所以不儲存除...

C debug模式下,VS輸出日誌

最近遇到了乙個很舊的專案需要維護,維護的產品是 windows mobile5.0 6.0的東東,這是05,06年的東西,10多年以前的了,沒辦法,只因為我是做移動端的,廢話不多說,上 吧 在網上看了下,大致是幾種情況 1.outputdebuginfo outputdebugstring 這些方法...

Activity的啟動模式與標誌位

共有4個值 1 在androidmenifest.xml檔案對應的activity標籤中指定,示例 android launchmode singletask 2 通過intent設定標誌位,示例 intent.addflags intent.flag activity new task 第2種指定...