从我所看到的,似乎有9种不同的旗帜。是否可以直接读取/更改它们?我知道我可以知道例如在执行cmp / jmp指令后是否设置了零标志,但我问是否可以做类似的事情
mov eax, flags
或其他什么。
另外,对于写作,是否可以手动设置它们?
答案 0 :(得分:27)
可以使用特定说明直接设置或清除某些标志:
对于读写符号,零,辅助进位,奇偶校验和进位标志,可以使用LAHF将低8位(这5个标志加3个不确定位)加载到AH寄存器中,并且您可以使用SAHF将AH中的值存储回标志寄存器。
您还可以使用PUSHF指令将标志推入堆栈,在堆栈上读取和修改它们,然后使用POPF指令将它们存储回标志寄存器。 / p>
请注意,您无法使用POPF设置VM和RF标志 - 它们保留以前的值。同样,只能在特权级别0执行时更改I / O特权级别,并且只能在特权级别执行时更改中断标志,至少与I / O特权级别一样具有特权。
答案 1 :(得分:8)
你可以使用pushf和popf指令将标志推入堆栈,你可以修改它们,然后将它们弹回。
答案 2 :(得分:5)
如果你只需要标志寄存器的低字节(包含SF,ZF,AF,PF,CF),那么有一个奇怪但方便的指令LAHF(哈哈),它加载了底部的8位flags注册到AH,以及其对应的SAHF将AH存储到标志中。
对于进位标志,x86提供CLC,STC和CMC,分别清除,设置和补充进位标志。
答案 3 :(得分:2)
最简单的方法是使用 pushf / popf 。
如果要将eflags
移至eax
,请使用下面的代码。
pushf # push eflags into stack
pop %eax # pop it into %eax
答案 4 :(得分: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:
答案 5 :(得分:0)
将标志的副本保存在变量中以便妥善保管
.data
saveflags BYTE ?
.code
lahf ; load flags into AH
mov saveflags,ah ; save them into a variable
SAHF:将AH存储到状态标志
检索先前存储的标志的值
.code
mov ah, saveflags ; load save flags into AH
sahf ; copy into flags register