C++11の新しい特性における匿名関数Lambda式のアセンブリ実装解析(三)
C++11の新しい特性における匿名関数Lambda式のアセンブリ実装解析(一)
C++11の新しい特性における匿名関数Lambda式のアセンブリ実装解析(二)
Lambda式の複雑な形式は次のとおりです.
簡単なLambda閉包関数を構築して解析した.
上記のコードでは、lambda式は、2つのパラメータaおよびbを渡し、cを参照でキャプチャし、計算後の結果をrに返す必要がある.
対応する符号化は以下の通りである.
明らかに、前の2つの文と同じように、ここでは簡単に説明します.
Lambda式ではcがキャプチャされているため、ここでは最初のlea命令は、cのアドレスをレプリケーション関数に渡し、2番目のlea命令は、この取得対象を記録するためのアドレスをレプリケーション関数に渡し、
呼び出しが発生した場合、2つのpushはstdcall方式でスタックを右から左に押します.アドレス用にthisが式に渡されました.
Lambda呼び出し済みの戻り値はデフォルトでeaxに格納されるため、ここで最後のmovは、閉パケットの関数戻り値をrに書き込むことを意味する.
では、閉パッケージ内で受信パラメータをどのように処理し、どのように返したかを見てみましょう.実は普通の関数のような原理で、以前の博文でも関数呼び出しのアセンブリ原理について話したことがありますが、ここで簡単に話しましょう.
パラメータ[ebp+8]=a;[ebp+0Ch] = b
eaxは一時的な量を置くことが多く、edxはアドレスを置くことが多い.この経験から、後の2つのmovが*this(得られたのは&c)を取り出し、a+bから*(&c)を減算した結果、eaxに置かれ、retは後供給主関数のrに戻って取得されることが容易にわかる.
3つのブログのまとめ:
C++11のlambda式は形式的に関数の書き方を変え、関数呼び出しをより簡潔で柔軟にし、閉パッケージ関数も多くの高級言語の特性の一つである.
Lambda式は不思議なものではなく、万変はその宗から離れず、彼は依然として1つの関数の形式でアセンブリに存在し、下層処理は普通の関数と基本的に同じである.
Lambda式と一般的な関数は、ソースプログラムの実装において異なります.
Lambda式は通常、パラメータとして別の関数に渡され、それ自体がcallbackとして機能し、他の場所で完全な関数を書くか、関数ポインタを使用することを避ける.
Lambda式と一般関数のアセンブリ層での実装はほぼ同じです.
最も特殊な点は、閉パケットで自分の役割ドメイン外の変数を使用する場合、「キャプチャ」が必要ですが、キャプチャは実は別の非表示(ソースコードが見えない)を通じて実現され、私はそれをコピー関数(または準備関数と呼ぶでしょう)と呼んで実現します.具体的な実装はキャプチャ方式によって異なり、ほぼ一連の付与文です.
閉じたパケットに入力されたthisポインタ(直接使用できない)によって、取得された変数またはオブジェクトが操作されます.
キャプチャ方式における値別または参照別の概念については,通常の関数と一致する.
さて、ここまで言うと、Lambda式の最下層実現の基本は、本シリーズの博文はすべてオリジナルで、オープンソースの中国OSChinaがこのような学習交流のプラットフォームを提供してくれたことに感謝しています.読者は他の見解があれば、コメントを歓迎します.
最後に皆さんに一言、オリジナルです.
車輪を繰り返す必要はありませんが、車輪を作る能力を持っていなければなりません.
C++11の新しい特性における匿名関数Lambda式のアセンブリ実装解析(二)
Lambda式の複雑な形式は次のとおりです.
[ capture ] ( params ) -> ret { body }
簡単なLambda閉包関数を構築して解析した.
int main()
{
int c = 10;
auto lambda = [&] (int a, int b)->int{
return a + b - c;
};
int r = lambda(1, 2);
return 0;
}
上記のコードでは、lambda式は、2つのパラメータaおよびbを渡し、cを参照でキャプチャし、計算後の結果をrに返す必要がある.
対応する符号化は以下の通りである.
int c = 10;
mov dword ptr [ebp-8],0Ah
auto lambda = [&] (int a, int b)->int{
return a + b - c;
};
lea eax,[ebp-8]
push eax
lea ecx,[ebp-14h]
call 010E13B0
int r = lambda(1, 2);
push 2
push 1
lea ecx,[ebp-14h]
call 010E1400
mov dword ptr [ebp-20h],eax
return 0;
xor eax,eax
明らかに、前の2つの文と同じように、ここでは簡単に説明します.
Lambda式ではcがキャプチャされているため、ここでは最初のlea命令は、cのアドレスをレプリケーション関数に渡し、2番目のlea命令は、この取得対象を記録するためのアドレスをレプリケーション関数に渡し、
呼び出しが発生した場合、2つのpushはstdcall方式でスタックを右から左に押します.アドレス用にthisが式に渡されました.
Lambda呼び出し済みの戻り値はデフォルトでeaxに格納されるため、ここで最後のmovは、閉パケットの関数戻り値をrに書き込むことを意味する.
では、閉パッケージ内で受信パラメータをどのように処理し、どのように返したかを見てみましょう.実は普通の関数のような原理で、以前の博文でも関数呼び出しのアセンブリ原理について話したことがありますが、ここで簡単に話しましょう.
pop ecx
mov dword ptr [ebp-8],ecx
return a + b - c;
mov eax,dword ptr [ebp+8]
add eax,dword ptr [ebp+0Ch]
mov ecx,dword ptr [ebp-8]
mov edx,dword ptr [ecx]
sub eax,dword ptr [edx]
パラメータ[ebp+8]=a;[ebp+0Ch] = b
eaxは一時的な量を置くことが多く、edxはアドレスを置くことが多い.この経験から、後の2つのmovが*this(得られたのは&c)を取り出し、a+bから*(&c)を減算した結果、eaxに置かれ、retは後供給主関数のrに戻って取得されることが容易にわかる.
3つのブログのまとめ:
C++11のlambda式は形式的に関数の書き方を変え、関数呼び出しをより簡潔で柔軟にし、閉パッケージ関数も多くの高級言語の特性の一つである.
Lambda式は不思議なものではなく、万変はその宗から離れず、彼は依然として1つの関数の形式でアセンブリに存在し、下層処理は普通の関数と基本的に同じである.
Lambda式と一般的な関数は、ソースプログラムの実装において異なります.
Lambda式は通常、パラメータとして別の関数に渡され、それ自体がcallbackとして機能し、他の場所で完全な関数を書くか、関数ポインタを使用することを避ける.
Lambda式と一般関数のアセンブリ層での実装はほぼ同じです.
最も特殊な点は、閉パケットで自分の役割ドメイン外の変数を使用する場合、「キャプチャ」が必要ですが、キャプチャは実は別の非表示(ソースコードが見えない)を通じて実現され、私はそれをコピー関数(または準備関数と呼ぶでしょう)と呼んで実現します.具体的な実装はキャプチャ方式によって異なり、ほぼ一連の付与文です.
閉じたパケットに入力されたthisポインタ(直接使用できない)によって、取得された変数またはオブジェクトが操作されます.
キャプチャ方式における値別または参照別の概念については,通常の関数と一致する.
さて、ここまで言うと、Lambda式の最下層実現の基本は、本シリーズの博文はすべてオリジナルで、オープンソースの中国OSChinaがこのような学習交流のプラットフォームを提供してくれたことに感謝しています.読者は他の見解があれば、コメントを歓迎します.
最後に皆さんに一言、オリジナルです.
車輪を繰り返す必要はありませんが、車輪を作る能力を持っていなければなりません.