順番に渡し、++ ++、C ++のパラメータ

コードの一部を見てください:

#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」である理由を理解するために組み合わせたアセンブリコードは、難しいことではありません、このような根本的な違いである(注:パラメータや表現の性能パラメータの読み取りが右から左にあるとき)

関数を呼び出すときに、混乱を避けるために、パラメータのインクリメントとデクリメントの使用を避けるために。


個々のと併せて読ま地元作家のための記事を書く、間違っている場合は、私を修正してください、ミスがあるかもしれません。

おすすめ

転載: www.cnblogs.com/fancyxie/p/11618369.html