FLAGSレジスタ

FLAGSレジスタは、 x86 CPUの現在の状態を保持するステータスレジスタです。フラグビットのサイズと意味はアーキテクチャに依存します。通常、このレジスタは算術演算の結果と、その時点でCPUの動作に課せられた制限に関する情報を反映します。これらの制限には、一部の割り込みのトリガーを禁止することや、特定のクラスの「特権」命令の実行を禁止することなどが含まれます。追加のステータスフラグは、メモリマッピングをバイパスし、算術オーバーフローが発生した場合にCPUが取るべきアクションを定義する場合があります。

キャリー、パリティ、補助キャリー (またはハーフ キャリー)、ゼロ、および符号フラグは、多くのアーキテクチャに含まれています (多くの最新の (RISC) アーキテクチャには、キャリーなどのフラグがありません。フラグを使用する場合でも、BCD 計算は一般的ではなくなり、x86-64ロング モードでもサポートが制限されているため、ハーフ キャリーはまれです)。

i286アーキテクチャでは、このレジスタは16ビット幅です。後継のEFLAGSレジスタとRFLAGSレジスタ(最近のx86-64)は、それぞれ32ビット64ビット幅です。幅の広いレジスタは、以前のより小さなレジスタとの互換性を維持しています。

Intel x86 FLAGSレジスタ[ 1 ]
少し #マスク略語説明カテゴリ=1=0
00x0001CF旗を運ぶ状態CY(キャリー)NC(キャリーなし)
10x0002予約済み、 EFLAGSでは常に1 [ 2 ] [ 3 ]
20x0004PFパリティフラグ状態PE(パリティイーブン)PO(パリティ奇数)
30x0008予約済み[ 3 ]
40x0010AF補助キャリー旗[ 4 ]状態AC(補助運搬)NA(補助キャリーなし)
50x0020予約済み[ 3 ]
60x0040ZFゼロフラグ状態ZR(ゼロ)NZ(ゼロではない)
70x0080SFサイン旗状態NG(ネガティブ)PL(ポジティブ)
80x0100TFトラップフラグ(シングルステップ)コントロール
90x0200もし割り込み有効フラグコントロールEI(割り込みを有効にする)DI(割り込み無効)
100x0400DF方向旗コントロールDN(ダウン)UP(アップ)
110x0800オーバーフローフラグ状態OV(オーバーフロー)NV(オーバーフローなし)
12~130x3000IOPLI/O 特権レベル(286+ のみ)、8086 および 186 では常にすべて 1システム
140x4000NTネストされたタスクフラグ(286+のみ)、8086と186では常に1システム
150x8000医学博士モードフラグ(NEC Vシリーズのみ)[ 5 ] 、すべてのIntel CPUで予約済み。8086 /186では常に1、286以降では0。コントロール(NECのみ)ネイティブモード( 186互換)(NECのみ)エミュレーションモード( 8080互換)
EFLAGS
160x0001 0000無線周波数再開フラグ(386以上のみ)システム
170x0002 0000仮想マシン仮想 8086 モードフラグ (386+ のみ)システム
180x0004 0000交流アライメント チェック (486+、リング 3)、SMAPアクセス チェック ( Broadwell +、リング 0-2)システム
190x0008 0000VIF仮想割り込みフラグ(Pentium+)システム
200x0010 0000VIP仮想割り込み保留中(Pentium+)システム
210x0020 0000IDCPUID命令が使用可能(Pentium+)システム
22~290x3FC0 0000予約済み
300x4000 0000(なし)AESキースケジュールロードフラグ[ 6 ] ( VIA PadLock搭載CPUのみ)システム
310x8000 0000人工知能代替命令セット対応(VIA C5XLプロセッサのみ)[ 7 ]システム
RFLAGS
32-630xFFFF FFFF… …0000 0000予約済み

注: 表のマスク列は、FLAGS レジスタ値内のフラグを照会するための ANDビットマスク( 16 進数値) です。

使用法

すべてのFLAGSレジスタには、条件コード(ある機械語命令の結果を別の命令に反映させるフラグビット)が格納されます。算術命令と論理命令は、これらのフラグの一部またはすべてをセットします。条件ジャンプ命令は、特定のフラグの値に基づいて様々な動作を実行します。例えば、jz(ゼロの場合ジャンプ)、jc(キャリーの場合ジャンプ)、jo(オーバーフローの場合ジャンプ)は、特定のフラグに依存します。その他の条件ジャンプは、複数のフラグの組み合わせをテストします。

FLAGSレジスタはスタックから移動したり、スタックから移動したりできます。これは、割り込みサービスルーチンなど、レジスタへの変更が呼び出しコードに認識されてはならないルーチンに対して、CPUコンテキストの保存と復元を行う処理の一部です。関連する命令は以下のとおりです。

  • PUSHF 命令と POPF 命令は、16 ビットの FLAGS レジスタを転送します。
  • PUSHFD/POPFD ( i386アーキテクチャで導入) は、32 ビットのダブル レジスタ EFLAGS を転送します。
  • PUSHFQ/POPFQ ( x86-64アーキテクチャで導入) は、64 ビットのクワッドワード レジスタ RFLAGS を転送します。

64ビットモードでは、PUSHF/POPFとPUSHFQ/POPFQは使用できますが、PUSHFD/POPFDは使用できません。[ 8 ]:4–349、4–432

FLAGS レジスタの下位 8 ビットは、SAHF および LAHF (AH をフラグにロード/ストア) による直接ロード/ストア操作にも使用できます。

FLAGSレジスタのプッシュとポップの機能により、プログラムは機械語命令では不可能な方法でFLAGSレジスタ内の情報を操作できます。例えば、cld命令stdはそれぞれ方向フラグ(DF)をクリアおよびセットしますが、DFを補完する命令はありません。これは、次のアセンブリコードで実現できます。

; これは 8086 コードで、16 ビット レジスタがスタックにプッシュされます。; この CPU では、フラグ レジスタは 16 ビットのみです。pushf ; スタックを使用して FLAGS を転送します。pop ax ; … を AX レジスタにプッシュします。 push ax ; それらをスタックにコピーして保存します。xor ax , 400h ; DF のみをトグル (反転、'補数') します。他のビットは変更されません。 push ax ; 再びスタックを使用して、変更された値を移動します。popf ; … を FLAGS レジスタにプッシュします。 ; ここで、DF フラグを補数にする必要のあるコードを挿入します。 popf ; FLAGS の元の値を復元します。

FLAGSレジスタを操作することで、プログラムは搭載されているプロセッサのモデルを特定できます。例えば、アライメントフラグは486以降でのみ変更できます。プログラムがこのフラグを変更しようとして、変更が保持されなかったと判断された場合、そのプロセッサは486より前のバージョンです。

Intel Pentium以降、CPUID命令はプロセッサモデルを報告します。ただし、上記の方法は以前のモデルを区別するのに依然として有用です。

参照

参考文献

  1. ^ Intel 64およびIA-32アーキテクチャソフトウェア開発者マニュアル(PDF) . 第1巻. 2012年5月. pp.  3– 21.
  2. ^ Intel 64およびIA-32アーキテクチャソフトウェア開発者マニュアル(PDF) . 第1巻. 2016年12月. p. 78.
  3. ^ a b c「シリコンリバースエンジニアリング:8085の文書化されていないフラグ」 www.righto.com . 2018年10月21日閲覧
  4. ^ Intel 64 および IA-32 アーキテクチャー ソフトウェア開発者マニュアル、第 1 巻。2022 年 12 月。3 ~ 16ページ 
  5. ^ NEC、 16ビットVシリーズ ユーザーズマニュアル、文書番号U11301E、2000年9月、p. 186
  6. ^ VIA、「PadLockプログラミングガイド」 v1.66、2005年8月4日、7-8ページ。 2010年5月26日時点のオリジナルよりアーカイブ。
  7. ^ VIA、 VIA C3 プロセッサ代替命令セットアプリケーションノート、バージョン 0.24、2002 - EFLAGS.AI フラグの詳細については、12 ページの図 2 と 21 ページの第 4 章を参照してください。
  8. ^ Intel 64およびIA-32アーキテクチャソフトウェア開発者マニュアル(PDF) . Vol. 2B. 2012年5月.