一条指令清除 PF(奇偶校验标志)——获取结果寄存器中的奇数位

Zom*_*ovy 5 x86 assembly micro-optimization parity

在 x86 汇编中,是否可以在任何初始寄存器配置下使用一条且仅一条指令清除奇偶校验标志?

这相当于使用任何设置标志的操作(明确排除)创建一个具有奇数位mov的结果寄存器。

相比之下,设置奇偶校验标志可以在一条指令中完成:

cmp bl, bl
Run Code Online (Sandbox Code Playgroud)

清除奇偶校验标志的方法有很多种,有两条指令:

and bl, 0 
or  bl, 1
Run Code Online (Sandbox Code Playgroud)

然而,单指令方法仍然难以实现。

Bre*_*dan 5

尝试这个:

foo:  cmp byte [foo],0x7F
Run Code Online (Sandbox Code Playgroud)

注:该cmp指令的第一个字节是0x80,0x80-0x7F = 0x01。

  • 我想这应该有一个 `cs:` 覆盖,因为我们可能不应该假设任何关于 `ds` 的内容。 (2认同)

Sev*_*yev 4

请参阅其他答案以了解技巧,例如使用内存内容或始终清除 PF 的较新指令,无论任何寄存器中的位模式如何。

在一条指令中可以清除 PF,但在不知道寄存器内容的情况下,从同一指令获取结果寄存器中的奇数位似乎是不可能的。(mov al, 1当然可以只做问题的后半部分而不影响标志)。

这个答案的其余部分是仅考虑问题中提出的方式编写的:在寄存器上使用传统的 ALU 指令,根据结果的低字节的奇偶校验设置 PF。


当应用于寄存器的两个副本时(如or al, al),任何 PF 更改指令都不能无条件地产生奇校验结果。and al, 0同样,当应用于寄存器和完全定义结果的常量(如或)时,所有算术命令都不会产生奇校验结果or al, ffh。至于第二个操作数是任何其他常量的命令,结果将取决于寄存器的初始值,我们无法控制它。

如果我们知道执行环境的一些细节,就有可能使用已知地址处的内存内容。在实模式下的 PC 兼容机上,您可以依赖 BIOS 数据结构。在 MS-DOS 中,可执行文件头也是如此。在 Windows 中,TEB 为FS:0.