IF とか EFLAGS とかを操作する命令たち
ia32 なプロセッサにおいてはマスク可能割り込みの制御のために EFLAGS レジスタというレジスタに IF (Interrupt Enable Flag) というフィールド (ってかビット) が用意されており、このフィールドの値でマスク可能ハードウェア割り込み要求に対する CPU の応答を制御しているとの事。
この EFLAGS というレジスタは限られた命令でしかレジスタ内の値を操作できないとの事で、以下に IF ビットの操作に関連する命令セットに限定して列挙。
- popf
スタックから pop した値を EFLAGS に設定 - pushf
EFLAGS の値をスタックに push - sti
IF の値を 1 に設定 (割り込み可能フラグを設定) - cli
IF の値を 0 に設定 (割り込み可能フラグをクリア) - iret
EIP、CS、EFLAGS (場合によっては SP、SS) レジスタをスタックから復帰し、割り込まれたプログラムの実行に戻る
これらの命令はamazon:Linuxカーネル解析入門の3章「同期と排他」において紹介されているマクロにて使用されている。
include/asm-i386/system.h より抜粋 (一部整形)
#define local_irq_restore(x) do { typecheck(unsigned long,x); \ __asm__ __volatile__("pushl %0 ; popfl" \ : /* no output */ \ :"g" (x) \ :"memory", "cc"); \ } while (0) #define local_irq_disable() __asm__ __volatile__("cli": : :"memory") #define local_irq_enable() __asm__ __volatile__("sti": : :"memory") #define local_irq_save(x) \ __asm__ __volatile__("pushfl ; popl %0 ; cli" \ :"=g" (x) \ : /* no input */ \ :"memory")
typecheck マクロについては略。
又、iret 命令については割り込み処理の現時点で分かっている部分のまとめなエントリを入れようと思っておりますのでそちらで可能な限りのフォローを入れてみたいと。
追記
IA-32 インテル®アーキテクチャ ソフトウェア・デベロッパーズ・マニュアル下巻 5.8.1.マスク可能ハードウェア割り込みのマスキングの項に STI および CLI 以外で IF フラグが影響を受ける操作が箇条書きにされている。以下に引用。