如何手动更改 8086 的标志(在汇编代码中)?

how to change flags manually (in assembly code) for 8086?

有没有办法手动更改每个标志?或者你是否必须使用一个你知道会改变它们的结果的命令?

基本上我正在使用命令 RCL,我不想一开始就得到 1,所以我想将 CF 更改为0,我知道我可以使用如下命令:

mov al, 0
shl al, 1

但我想知道是否有任何其他方法可以做到这一点,而无需使用其他命令结果。

我也想知道你的方法是否可以告诉我,也可以用来改变所有的标志,不仅是CF,还有OF,ZF,和依此类推

没有任何指令将 eflags 视为读写 GP 寄存器。
引用英特尔1:

Some of the flags in the EFLAGS register can be modified directly, using special-purpose instructions (described in the following sections). There are no instructions that allow the whole register to be examined or modified directly.
The following instructions can be used to move groups of flags to and from the procedure stack or the EAX register:
LAHF, SAHF, PUSHF, PUSHFD, POPF, and POPFD. After the contents of the EFLAGS register have been transferred to the procedure stack or EAX register, the flags can be examined and modified using the processor’s bit manipulation instructions (BT, BTS, BTR, and BTC).

eflags寄存器分为三组:状态标志控制标志系统旗帜.

状态标志中,只有CF可以直接用clcstccmc.
没有读取 CF 的指令,但您可以使用 cmovccadcsetcc 等指令间接读取它。 所有其他标志都需要使用专门定制的算术指令或通过将 eflags 状态组 内容复制到 ah(使用 lahf)或堆栈(使用 pushfd)然后返回到 eflags(使用 sahfpopfd)。

Control flags组中只有DF可以用cldstd操作.
要读取 DF 的当前值,您需要使用 pushfd

系统标志通常通过执行一些特权操作来间接操纵,例如切换任务、进入 v86 模式等。
IF可以直接用clisti操作。
所有其他标志只能使用 pushfd/popfd 进行操作。


供参考:

  • 在 64 位模式下,标志寄存器是 rflags,但目前保留高 32 位,因此 rflags 被处理为 eflags
  • pushfdeflags 压入堆栈。还有一个 16 位版本 pushf,它只压入 eflags 的低 16 位。 popfd/popf 相同。
  • lahf/sahf 只复制状态标志。

1 英特尔手册,第 1 卷,第 3.4.3 节。