私が読んだことから、9つの異なるフラグがあるようです。それらを直接読み取ったり変更したりすることは可能ですか?たとえば、cmp / jmp命令を実行した後にゼロフラグが設定されているかどうかはわかりますが、次のようなことが可能かどうかを尋ねています。
mov eax, flags
か何か。
また、書くために、手で設定することは可能ですか?
一部のフラグは、特定の手順で直接設定またはクリアできます。
符号、ゼロ、補助キャリー、パリティ、およびキャリーフラグの読み取りと書き込みでは、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を設定またはクリアするシーケンスも簡単で、フラグを反転する場合としない場合があります。
フラグをスタックにプッシュするpushfおよびpopf命令を使用して、フラグを変更してから、元に戻すことができます。
フラグレジスタの下位バイト(SF、ZF、AF、PF、CFを含む)のみが必要な場合は、フラグレジスタの下位8ビットをロードする奇妙で便利な命令LAHF(ha ha)があります。 AH、およびAHをフラグに格納するための対応するSAHF。
特にキャリーフラグの場合、x86は、キャリーフラグをクリア、設定、および補完するために、それぞれCLC、STC、およびCMCを提供します。
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:
保管のためにフラグのコピーを変数に保存します
.data
saveflags BYTE ?
.code
lahf ; load flags into AH
mov saveflags,ah ; save them into a variable
SAHF:AHをステータスフラグに格納します
以前に保存されたフラグの値を取得します
.code
mov ah, saveflags ; load save flags into AH
sahf ; copy into flags register
最も簡単な方法は、pushf/popfを使用することです。
eflags
に移動したい場合はeax
、以下のコードを使用してください。
pushf # push eflags into stack
pop %eax # pop it into %eax