にはlinux/arch/x86/include/asm/switch_to.h
、マクロの定義がありswitch_to
、実際のスレッド切り替えの奇跡を行う主要な行は次のようになっています (Linux 4.7 で変更されるまで):
asm volatile("pushfl\n\t" /* save flags */ \
pushl %%ebp\n\t" /* save EBP */ \
"movl %%esp,%[prev_sp]\n\t" /* save ESP */ \
"movl %[next_sp],%%esp\n\t" /* restore ESP */ \
"movl $1f,%[prev_ip]\n\t" /* save EIP */ \
"pushl %[next_ip]\n\t" /* restore EIP */ \
__switch_canary \
"jmp __switch_to\n" /* regparm call */ \
"1:\t" \
"popl %%ebp\n\t" /* restore EBP */ \
"popfl\n" /* restore flags */ \
名前付きオペランドには、 のようなメモリ制約があります[prev_sp] "=m" (prev->thread.sp)
。 __switch_canary
が定義されていない限り、何も定義されていませんCONFIG_CC_STACKPROTECTOR
(その後、 を使用してロードおよびストアされます%ebx
)。
カーネルスタックポインターのバックアップ/復元のように、それがどのように機能するか、push next->eip
および実際の命令と一致する「偽の」呼び出し命令である関数の最後の命令でjmp __switch_to
どのように機能するかを理解し、効果的に戻ります次スレのポイント。ret
ret
next->eip
私が理解できないのは、なぜハッキングなのかということです。だけではなくcall __switch_to
、その後に、ret
よりクリーンで読みやすいです。jmp
next->eip