0
// gcc -g stack.c -o stack  
//  
unsigned long sp(void){ __asm__("mov %esp, %eax");}  
int main(int argc, char **argv)  
{  
    unsigned long esp = sp();  
    printf("Stack pointer (ESP : 0x%lx)\n",esp);  
    return 0;  
}

上記のコードを確認してください。実際、sp()はesp->eaxを介してespレジスタ値を返します。しかし、なぜ?sp()のデフォルトの戻り値はeax?誰がそれについてもっと教えてくれますか?ありがとう!

4

3 に答える 3

5

プロセッサアーキテクチャが引数、呼び出し、および戻り値(およびカーネルへのsyscall)を編成する方法、つまり呼び出し規約は、ABI(アプリケーションバイナリインターフェイス)で指定されています。Linux on x86-64の場合は、x86-64ABIドキュメントを読む必要があります。そして、はい、aを返す関数の戻り値はx86-64longではスルーです。( X32 ABI%eaxもあります)

これはほとんど従来型ですが、規則が変更された場合は、コンパイラ、おそらくリンカ、カーネル、およびすべてのライブラリを変更する必要があることに注意してください。実際、プロセッサメーカーが既存のABIを念頭に置いてシリコンを設計することは非常に重要です(たとえば、%espレジ​​スタ、SYSENTER命令などの重要性)。

于 2012-10-06T16:33:00.443 に答える
2

これがルールです!

GCCが32ビットアセンブリに使用する呼び出し規約は、整数を返す関数の戻り値がの値になることです%eax。GCCはこれをインラインアセンブリ機能にも採用しています。

詳細については、ウィキペディアを参照してください。

于 2012-10-06T16:33:15.263 に答える
-1

IIRCの正しいコマンドは、「mov esp、eax」ではなく「mov eax、esp」である必要があります。

unsigned long sp(void){ __asm__("mov %eax, %esp");} 
于 2012-10-06T16:54:05.777 に答える