コードの一部を見てください:
#include<iostream>
using namespace std;
void func(int a, int b)
{
cout << a << " " << b << endl;
}
int main()
{
int a = 0;
func(a++, ++a);
return 0;
}
C ++は、スタック上に右から左にあるので、私は結果が「11」(++最初のスタックになると思い、これだけのコードを参照して、(コンパイラではなく、C ++標準の規定に該当する契約を呼び出します)その後、++スタック)が、実際には、 次のとおりです。これは、VSがG ++で実行されているの上にある同じ結果です。幸いなことに、VSはまた、アセンブリコードを表示することができます。
そこにVSで非常に便利な分解ツールがあり、そう言うために次のことをVS2019に基づいているので分解しています。
ブレークポイントとデバッグを設定し、あなたが逆アセンブルウィンドウで開くことができます。
関数func呼び出されたアセンブリコードの以下の部分を:
mov eax,dword ptr [a]
add eax,1
mov dword ptr [a],eax //这三行指令将a+1
mov ecx,dword ptr [a]
mov dword ptr [ebp-0D0h],ecx //这两行指令将a的值存储到一个临时地址(寄存器间接寻址)中
mov edx,dword ptr [a]
add edx,1
mov dword ptr [a],edx /这三行指令又将a+1
mov eax,dword ptr [a]
push eax //这两行指令将a压入栈
mov ecx,dword ptr [ebp-0D0h]
push ecx //这两行指令将刚刚存储的临时地址的值压入栈
call func (0A312E9h) //调用func函数
add esp,8 //esp为栈指针寄存器
コードが変更された場合
FUNC(++、++ a)は、
何が起こるのでしょうか?答えは
mov eax,dword ptr [a]
add eax,1
mov dword ptr [a],eax //这三行指令将a+1
mov ecx,dword ptr [a]
add ecx,1
mov dword ptr [a],ecx //这三行指令将a+1
mov edx,dword ptr [a]
push edx //这两行指令将a压入栈
mov eax,dword ptr [a]
push eax //这两行指令将a压入栈
call func (09912E9h)
add esp,8
、++ ++後、変更を見ることができ、最大保存するためのステップの少ない値を命じるだけで式を実行するすべてのパラメータの後、およびスタックにパラメータを読み込むときにそうではありませんので、圧入、スタックの最後のパラメータは、最終的な変数Aに押圧されます。
次に、資料の冒頭には「12」である理由を理解するために組み合わせたアセンブリコードは、難しいことではありません、このような根本的な違いである(注:パラメータや表現の性能パラメータの読み取りが右から左にあるとき):
関数を呼び出すときに、混乱を避けるために、パラメータのインクリメントとデクリメントの使用を避けるために。
個々のと併せて読ま地元作家のための記事を書く、間違っている場合は、私を修正してください、ミスがあるかもしれません。