int x = 5;
void foo()
{
long unsigned r[8];
memset(&r, 0, sizeof(long unsigned) * 8);
__asm {
pushad;
pop r[7];
pop r[6];
pop r[5];
pop r[4];
pop r[3];
pop r[2];
pop r[1];
pop r[0];
}
printf("Register values: \n");
printf("eax: %lu\n", r[0]);
printf("ecx: %lu\n", r[1]);
printf("edx: %lu\n", r[2]);
printf("ebx: %lu\n", r[3]);
printf("esp: %lu\n", r[4]);
printf("ebp: %lu\n", r[5]);
printf("esi: %lu\n", r[6]);
printf("edi: %lu\n", r[7]);
if (--x) { foo(); }
}
int main()
{
foo();
return 0;
}
再帰関数でpushadを使用して、どのようにのGPRS変更を確認しようとしていたときに増加していないようです。しかし、私はr(0)を除いて、これらのすべてのために0のプリントアウトを得ているようですが、foo()コールごとに44ずつ降順に数字が出力されます。あれは正しいですか?スタックポインタは、私はちょうどpushad/PUSHA操作について学んだ
新しい機能を呼び出すたびにespレジスターが動くべきではないと思いますが、少しわかりますか?
通常、 'pushad' /' popad'は使用しないでください。遅いですし、すべてのレジスタを保存/復元する必要はほとんどありません。 (通常、関数はeax/ecx/edxを壊す可能性があります)。また、MSVCスタイルのインラインasmでは、レジスタを自分で保存/復元する必要はありません。コンパイラは保存する必要がある場合に使用するレジスタを保存します。 (あなたのコードがすでに 'ebx'、' esi'などを保存しているもっと大きな関数にインライン展開されているとします) –
@PeterCordesああ、私は注意します!私たちが与えたユーザレベルのスレッド割り当ては、pushadとpopad(esp、ebp、eip以外のレジスタはほとんどわかりません)だけをカバーしていました。 – ozma