23

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

mov eax, flags

か何か。

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

4

6 に答える 6

34

一部のフラグは、特定の手順で直接設定またはクリアできます。

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

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

また、 PUSHF命令を使用してフラグをスタックにプッシュし、スタック上でフラグを読み取って変更してから、POPF1命令を使用フラグをフラグレジスタに格納することもできます。

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


脚注1:

popf最近のCPUでは非常に遅いことに注意してください。AgnerFogの最適化ガイドと手順表を参照してください。カーネルモードではIFとAC、およびIO特権レベルを変更できるため、マイクロコード化されています。デコーダーはモードセンシティブではないため、現在のCPUのモードに関係なくペナルティが発生します。

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

于 2009-09-14T04:05:54.570 に答える
8

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

于 2009-09-10T18:05:55.093 に答える
7

フラグレジスタの下位バイト(SF、ZF、AF、PF、CFを含む)のみが必要な場合は、フラグレジスタの下位8ビットをロードする奇妙で便利な命令LAHF(ha ha)があります。 AH、およびAHをフラグに格納するための対応するSAHF。

特にキャリーフラグの場合、x86は、キャリーフラグをクリア、設定、および補完するために、それぞれCLC、STC、およびCMCを提供します。

于 2009-09-14T03:46:06.163 に答える
2

SETcc

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

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

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

于 2015-06-20T09:48:49.450 に答える
1
  • LAHF:ステータスフラグをAHにロードします
  • サイン、ゼロ、およびキャリーフラグを含むEFLAGSレジスタの下位バイトをコピーします。
  • 保管のためにフラグのコピーを変数に保存します

    .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 
    
于 2012-11-21T12:31:16.877 に答える
1

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

eflagsに移動したい場合はeax、以下のコードを使用してください。

pushf                  # push eflags into stack
pop %eax               # pop it into %eax
于 2019-01-23T11:54:52.710 に答える