質問

私が読んだことからすると、9つの異なるフラグがあるようです。それらを直接読み取り/変更することは可能ですか?たとえば、cmp / jmp命令を実行した後にゼロフラグが設定されているかどうかはわかりますが、次のようなことができるかどうかを尋ねています

mov eax, flags

または何か。

また、書くために、それらを手で設定することは可能ですか?

役に立ちましたか?

解決

いくつかのフラグは、特定の指示で直接設定またはクリアできます:

  • CLC STC 、および CMC :キャリーフラグをクリア、設定、補完
  • CLI および STI :割り込みフラグをクリアして設定します(アトミックに実行する必要があります)
  • CLD および STD :方向フラグをクリアして設定します

符号、ゼロ、補助桁上げ、パリティ、桁上げフラグの読み取りと書き込みには、 LAHF を使用して下位8ビット(5つのフラグと3つの不確定ビット)をAHレジスタにロードします。 SAHF は、AHからそれらの値をフラグレジスタに保存します。

PUSHF 命令も使用できます。フラグをスタックにプッシュするには、スタックでフラグを読み取って変更し、 POPF 1 命令を使用してフラグレジスタに保存します。

POPFではVMおよびRFフラグを設定できないことに注意してください。以前の値は保持されます。同様に、特権レベル0で実行する場合にのみI / O特権レベルを変更でき、少なくともI / O特権レベルと同じ特権レベルで実行する場合にのみ割り込みフラグを変更できます。


脚注1:

最近のCPUでは popf は非常に遅いことに注意してください。 Agner Fogの最適化ガイドと手順表をご覧ください。カーネルモードではIFとAC、およびIO特権レベルを変更できるため、マイクロコード化されています。デコーダーはモードに依存しないため、現在のCPUのモードに関係なくペナルティを受けます。

可能であれば、パフォーマンスのためにpushf / popfの代わりにlahf / sahfを使用するか、または setc al のような重要なフラグを保存し、後で add al、255 CF =(AL!= 0)を設定します。または、 setnc al / sub al、1 など。 0または1レジスタに基づいてSFまたはOFを設定またはクリアするシーケンスも簡単です。フラグを反転するかどうかは関係ありません。

他のヒント

pushfおよびpopf命令を使用して、フラグをスタックにプッシュし、それらを変更してからポップオフすることができます。

フラグレジスタの下位バイト(SF、ZF、AF、PF、CFを含む)のみが必要な場合は、奇数ですが便利な命令LAHF(ha ha)があります。フラグはAHに登録され、対応するSAHFはAHをフラグに保存します。

特にキャリーフラグについては、x86はCLC、STC、およびCMCを提供し、それぞれキャリーフラグをクリア、設定、および補完します。

最も簡単な方法は、 pushf / popf を使用することです。

eflags eax に移動する場合は、以下のコードを使用します。

pushf                  # push eflags into stack
pop %eax               # pop it into %eax

SETcc

この命令ファミリは、いくつかのフラグ/フラグの組み合わせを観察する別の方法です。

個々のフラグに基づいてバイトの値を設定します。

例: CF の場合:

stc
setc al
; al == 1

clc
setc al
; al == 0

アップストリーム実行可能なGitHubアップストリームアサーション付き

Jcc

この命令ファミリは、もちろん特定のフラグの別の可能性であり、 SETcc の実装に使用できます:

jc set
mov al, 0
jmp end
set:
mov al, 1
end:

アップストリーム実行可能GitHubアップストリームアサーション付き

  • LAHF:ステータスフラグをAHに読み込みます
  • EFLAGSレジスタの下位バイトをコピーし、Sign、Zero、およびCarryフラグを含めます。
  • フラグのコピーを安全のために変数に保存します

    .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 
    
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top