2009-09-10 77 views
13

從我讀過的東西看,好像有9個不同的標誌。是否可以直接讀取/更改它們?我知道我可以知道,例如,如果零標誌是做了CMP/JMP指令後確定,但我問是否有可能像做如何直接讀寫x86標誌寄存器?

mov eax, flags 

什麼的。

此外,爲了寫作,是否可以手動設置它們?

+0

相關:HTTPS:/ /en.wikipedia.org/wiki/FLAGS_register有一個映射,其中的標誌是'pushf'或'lahf'之後的哪個標誌。 – 2017-11-26 07:27:40

回答

27

一些標誌可以設置或直接與特定的指令時清:

  • CLCSTCCMC:清晰,設置,以及相配套的進位標誌
  • CLISTI:清晰,設置中斷標誌(應該原子地完成)
  • CLDSTD:清除並設置方向標誌

對於讀取和寫入符號,零,輔助進位,奇偶校驗和進位標誌,可以使用LAHF將較低的8位(這5個標誌加上3個不確定位)加載到AH寄存器中,並且可以使用SAHF將這些來自AH的值存回標誌寄存器。

您也可以使用PUSHF指令將標誌壓入堆棧,在堆棧中讀取和修改它們,然後使用指令POPF將它們存回標誌寄存器。

請注意,您不能使用POPF設置VM和RF標誌 - 它們保留以前的值。同樣,只能在特權級別0執行時更改I/O特權級別,並且只能在至少與特權級別相同的特權級別執行時更改中斷標誌。

+4

更準確地說:英特爾手冊將每個標誌分類爲:狀態,控制或系統。系統標誌不能由用戶級應用程序修改。 – 2015-04-28 17:42:34

8

您可以使用pushf和popf指令將標誌推入堆棧,您可以修改它們,然後將它們彈出。

5

如果你只需要標誌寄存器(包含SF,ZF,AF,PF,CF)的低位字節,那麼存在奇怪而方便的LAHF指令(哈哈),它加載了8位這些標誌寄存到AH中,並且其對應的SAHF將AH存儲到標誌中。

對於進位標誌,x86提供了CLC,STC和CMC,分別對進位標誌進行清零,置位和補充。

0
  • LAHF:負載狀態標記爲AH
  • 複製EFLAGS的低字節寄存器包括符號,零和進位標誌。
  • 保存標誌的變量的副本保管

    .data 
    saveflags BYTE ? 
    .code 
    lahf ; load flags into AH 
    mov saveflags,ah ; save them into a variable 
    
  • SAHF:商店AH社會地位的標誌

  • 複製AH入EFLAGS的低字節寄存器
  • 檢索以前存儲的標誌的值

    .code 
    mov ah, saveflags ; load save flags into AH 
    sahf ; copy into flags register 
    
1

SETcc

該指令族是另一種觀察某些標誌/標誌組合的方法。例如,對於CF

stc 
setc al 
; al == 1 

clc 
setc al 
; al == 0 

JCC

該指令的家庭當然是對某些標誌的另一種可能性,並且可以用來實現SETcc

jc set 
mov al, 0 
jmp end 
set: 
mov al, 1 
end: