誰かが次のコードを理解するのを手伝ってくれたらありがたいですありがとう
if (iins->uInstr.mnemonic == UD_Ipop)
regsUsed = (regsUsed & ~(LYNX_ESP | LYNX_SP));
2 行目は次のようになりregUsed &= ~(LYNX_ESP | LYNX_SP);
ます (そして、なぜこのように書く人がいるのか、私にはほとんど想像できません)。
おそらく LYNX_ESP と LYNX_SP は、(おそらく) それぞれに 1 つのビットが設定された値であり、次のようなものです。
LYNX_EAX 1 ; 00000001b
LYNX_EBX 2 ; 00000010b
LYNX_ECX 4 ; 00000100b
; ...
LYNX_SP 64 ; 01000000b
LYNX_ESP 128 ; 10000000b
Or
これら ( (LYNX_SP | LYNX_ESP)
) を実行すると、両方のビットが設定された値が得られます。not
その ( ) をビット単位で~
実行すると、すべてのビットが反転するため、これらの 2 つのビットがクリアされ、他のすべてのビットが設定されます。次にand
、結果の値と の現在の値の間でビット単位の処理を行いregsUsed
、これらの 2 つのビットをクリアし、他のすべてのビットを変更しません。
より高いレベルから見ると、負の(アクティブロー)ロジックを使用していると思います。つまり、ビットがクリアさregsUsed
れていると、レジスタが使用されていることを示します。このより高い観点では、基本的に、のpop
ような命令pop ebx
は だけEBX
でなく/も使用すると言っています。SP
ESP
気にする理由については、これは、命令を並行して実行できるタイミング/かどうかを判断するために CPU が行うことのようなものです。たとえば、次のようなものがあるとします。
pop ecx
pop ebx
pop eax
これら 3 つすべてを並行して簡単に実行できないことは (必然的に) すぐにはわかりません。それぞれが異なるレジスタに書き込みますがSP
、3 つすべてが/の値に依存して変更しますESP
。上記のコードは、この依存関係の抽出/追跡に専念しているようです。
ニーモニックが のUD_Ipop
場合、LYNX_ESP
およびLYNX_SP
レジスタは使用されません。
もう少し:
LYNX_ESP
そして、LYNX_SP
1 ビットのみが設定された値を持つことになります。LYNX_ESP
is0x01
とLYNX_SP
isとしましょう0x02
。
(LYNX_ESP | LYNX_SP) -> (0x01 | 0x02) -> 0x03 (00000011b)
~(LYNX_ESP | LYNX_SP) -> 0xfc (11111100b)
regsUsed can be anything; ????????b
(regsUsed & ~(LYNX_ESP | LYNX_SP)) -> (????????b & 11111100b) -> ??????00b
LYNX_ESP
そのため、LYNX_SP
inを表すビットをオフにしregsUsed
、他のビットをそのまま保持します。
「ulnstr.mneminic が UD_lpop と等しい場合、LYNX_ESP および/または LYNX_SP で 1 に設定されているすべてのビットを regsUsed でクリアします」
コードは、特定のフラグを設定するためにビットごとの計算を行っています。ここに不十分な説明をすぐに書く代わりに、何が起こっているかを説明するこの記事にリンクします。