3

私はスタックの目的について少し哲学を持っており、コーディングを行った後、それがどのような強みであるかを理解しました。私の胃の中にある唯一のものは、それが機能とどのように機能するかということです。ユニバーサルレジスタを使用して2つの数値を加算する簡単な関数を作成しようとしましたが、たとえばCではそうではないと思います。すべてのパラメータ、ローカル変数はどこにあり、結果はどこに保存されますか?

これをアセンブラにどのように書き直しますか?(Cのコンパイラはどのように書き直しますか?)

int function(int a, int &b, int *c){
 return a*(b++)+(*c);
}

私はこの例がちょっとひどいことを知っています..しかし、このようにして私はすべての可能性を理解することができます

4

3 に答える 3

5

まず、参照(int&)はCではなく、C++だけです。

gccの内部で何が起こっているかを確認したい場合は、-Sフラグを使用してください。実際のプログラムは必要ありません。

g++ -S func.c

func.s(x86ボックス上のマイナスヘッダーなど)を含むファイルを作成します。

    .text
.globl __Z8functioniRiPi
__Z8functioniRiPi:
LFB2:
    pushq   %rbp
LCFI0:
    movq    %rsp, %rbp
LCFI1:
    movl    %edi, -4(%rbp)
    movq    %rsi, -16(%rbp)
    movq    %rdx, -24(%rbp)
    movq    -16(%rbp), %rax
    movl    (%rax), %edx
    movl    %edx, %ecx
    imull   -4(%rbp), %ecx
    movq    -24(%rbp), %rax
    movl    (%rax), %eax
    addl    %eax, %ecx
    incl    %edx
    movq    -16(%rbp), %rax
    movl    %edx, (%rax)
    movl    %ecx, %eax
    leave
    ret

C ++の名前マングリング(__Z8functioniRiPi)に注意してください。ここで、g++に-O2フラグを付けます。

    .text
    .align 4,0x90
.globl __Z8functioniRiPi
__Z8functioniRiPi:
LFB2:
    pushq   %rbp
LCFI0:
    movq    %rsp, %rbp
LCFI1:
    movl    (%rsi), %ecx
    movl    %ecx, %eax
    imull   %edi, %eax
    addl    (%rdx), %eax
    incl    %ecx
    movl    %ecx, (%rsi)
    leave
    ret

-O3同じコードを与えます。最適化するものは他にありません。

組み立てを楽しんでください。^ _ ^

于 2010-03-10T19:09:55.087 に答える
5

あなたが探しているのは、呼び出し規約に関する情報です。関数が呼び出されて返される方法は、プロセッサアーキテクチャ、コンパイラ、オペレーティングシステムなど、多くのものに依存します。パラメータと戻り値が正しく渡されるためには、呼び出し元と呼び出し先が規則に同意する必要があります。

于 2010-03-10T18:46:33.537 に答える
3

アーロンが規約の呼び出しについて言ったことは正解です。私自身の個人的なトピックの調査では、Smashing the Stack For Fun and Profitは、スタックフレームの役割と、それが破損したときに何が起こる可能性があるかについての優れた演習であることがわかりました。Finlayアセンブラーの重要な概念と、デバッガーで実行できる楽しいことを説明する、ハッカー向けのアセンブリ入門書をお勧めします。

于 2010-03-10T19:00:35.277 に答える