volatile
かそのfunction
がWindows CS_SYSCALL呼び出し規約を使用して、すなわち、__syscall
宣言されている場合、EAX
はWindows上での関数呼び出しを行う前に直接を初期化しなければならないであろう理由だけ技術理由でした。概念的には、これは%al
に%xmm
レジスタで渡された浮動小数点型引数の数が含まれているUN * X x86_64の規則に少し似ています。
Windows上のsyscall呼び出し規約は、__cdecl
と同じです。つまり、スタック上の関数argsは逆順になりますが、AL
には引数の数が含まれています。これは、通常、最後の最後にあるカーネルコードが、ユーザースタックからカーネルスタックに読み込んでargsを取得するためのデータの量を知るように行われます。
EAX
は、32ビットWindows上のすべての呼び出し規則のスクラッチレジスタであり、その値は関数呼び出しに対して保持されず、呼び出しを行う前に直接初期化することは冗長です。たとえ変数が保持されていても、単純な再読み込みはメモリバリアではなく、前のストアを「コミット」しないため、volatile
です。さらに、場所[EBP - 4]
はスタックの範囲内にあるため、変数はローカルです(また、volatile
修飾子はほとんど意味がありません)。それは逃した最適化ではない場合
は、それは
__syscall printf_syscall_conv(char *fmt, ...);
void possibly_print_three_vals(char *fmt, int val1, int val2, int val3)
{
if (*strchr('%', fmt) == '\0') // if no "%" in fmt, pass no args
printf_syscall_conv(fmt);
else
printf_syscall_conv(fmt, val1, val2, val3);
}
これはおそらく、あなたのようなアセンブリ出力を作成することができ、仮に引数などの異なる数、と__syscall function(...)
の呼び出しである可能性があります。
コンパイラがこれよりも愚かなことをしたのを見たことがあります... – Mysticial
@Mysticial:Oh lol ...私はこれに気づいたのは初めてです。 :)よく知っています。 – Mehrdad
おそらく、最初のプッシュへの分岐があります。 –