だから私はシステムの中期を勉強しています、そして同様のコースの古い中期はこの問題を抱えていました、Cとアセンブリコードは次のとおりです:
int gcd(int a, int b)
{
if(!b)
{
return a;
}
return gcd(b, a%b);
}
0x08048394 <+0>: push %ebp
0x08048395 <+1>: mov %esp,%ebp
0x08048397 <+3>: sub $0x10,%esp
0x0804839a <+6>: mov 0x8(%ebp),%eax
0x0804839d <+9>: mov 0xc(%ebp),%ecx
0x080483a0 <+12>: test %ecx,%ecx
0x080483a2 <+14>: je 0x80483b7 <gcd+35>
0x080483a4 <+16>: mov %eax,%edx
0x080483a6 <+18>: sar $0x1f,%edx
0x080483a9 <+21>: idiv %ecx
0x080483ab <+23>: mov %edx,0x4(%esp)
0x080483af <+27>: mov %ecx,(%esp)
0x080483b2 <+30>: call 0x8048394 <gcd>
0x080483b7 <+35>: leave
0x080483b8 <+36>: ret
%espの開始値は0xffff1000であり、gcd(213、18)の結果はgcd(213、18)、gcd(18、15)、gcd(15、3)、およびgcdになることがわかります。 (3、0)。次に、gcd(15、3)の戻り命令を実行する前に、%espの値を尋ねます。
解決策はそれが0xffff0fccであることを示しています。理由がよくわかりません。これが私の推論です:
0x10を3回減算し、gcd(18、15)とgcd(15、3)を呼び出しました。これらを組み合わせて、スタックから0x30と0x8を減算する必要があります。だから私たちは0xffff0fc8にいるべきではありませんか?次に、戻った後、$ espが0xffff0fccになるように、もう一度0x4を追加しますが、前ではありませんか?