15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
NT | IOPL | OF | DF | IF | TF | SF | ZF | AF | PF | CF | |||||
未 使 用 | 嵌 套 标 志 | I/O 权限 标志 占2位 | 溢 出 标 志 | 方 向 标 志 | 中 断 允 许 标 志 | 单 步 标 志 | 符 号 标 志 | 零 标 志 | 未 使 用 | 辅 助 标 志 | 未 使 用 | 奇 偶 标 志 | 未 使 用 | 进 位 标 志 |
上表是 32 位寄存器 EFLAGS 的低 16 位.
不能直接读写 EFLAGS, 但有些方便的指令, 如:
LAHF: 读取EFLAGS 低 8 位到 AH; SAHF 是 LAHF 的反向操作.
指令 STC、CLC、CMC 分别是给 CF(进位标志) 置位、复位、取反
; Test20_1.asm
.386
.model flat, stdcall include windows.inc
include kernel32.inc
include masm32.inc
include debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib .data
szBin1 db dup(?),
szBin2 db dup(?),
szBin3 db dup(?),
szBin4 db dup(?),
.code
main proc
stc ;置位 CF, CF = 1
lahf
invoke byt2bin_ex, ah, addr szBin1
clc ;复位 CF, CF = 0
lahf
invoke byt2bin_ex, ah, addr szBin2
stc
cmc ;取反 CF, CF = not CF
lahf
invoke byt2bin_ex, ah, addr szBin3
clc
cmc ;取反 CF, CF = not CF
lahf
invoke byt2bin_ex, ah, addr szBin4 PrintString szBin1 ;xxxxxxx1
PrintString szBin2 ;xxxxxxx0
PrintString szBin3 ;xxxxxxx0
PrintString szBin4 ;xxxxxxx1
ret
main endp
end main
如果要观察整个 EFLAGS 的 32 个位, 可用 PUSHFD 和 POPFD 指令让 EFLAGS 进栈、出栈
; Test20_2.asm
.586p
.model flat, stdcall include windows.inc
include kernel32.inc
include masm32.inc
include debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib .data
szBin db dup(?),
.code
main proc
stc
pushfd
invoke dw2bin_ex, dword ptr [esp+], addr szBin
popfd
PrintString szBin ;00000000000000000000001001000111
clc
pushfd
invoke dw2bin_ex, dword ptr [esp+], addr szBin
popfd
PrintString szBin ;00000000000000000000001010000110
ret
main endp
end main
发现标志寄存器里的数据有点捉摸不定, 看来不应该是这么观察的; 以后慢慢留意吧.