2009-09-10 76 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: