好友
阅读权限30
听众
最后登录1970-1-1
|
发现新人对前置、后置++操作都比较困惑,那么它们的区别到底再哪呢?我们通过汇编代码来分析就知道了。
先上我们的示例代码:
[C] 纯文本查看 复制代码 1 2 3 4 5 6 7 8 | int main()
{
int a=5,b=0,c=0,d=0;
b=++a;
c=a++;
d=a;
return 0;
}
|
下面来看看上面代码在QtCreator中的汇编代码:
下面分析汇编代码,很简单:
变量初始化代码:
[Asm] 纯文本查看 复制代码 1 2 3 4 | mov DWORD PTR [ esp +0xc],0x5 给变量a赋初始值
mov DWORD PTR [ esp +0x8],0x0 给变量b赋初始值
mov DWORD PTR [ esp +0x4],0x0 给变量 c 赋初始值
mov DWORD PTR [ esp ],0x0 给变量d赋初始值
|
可以看到,几个变量都是在栈中分配空间的。
b=++a代码:
[Asm] 纯文本查看 复制代码 1 2 3 | add DWORD PTR [ esp +0xc],0x1 给a加上1
mov eax , DWORD PTR [ esp +0xc] 将a的值拷贝到 eax 寄存器
mov DWORD PTR [ esp +0x8], eax 将 eax 寄存器的值再拷贝给b
|
从上面可以看出,和我们想的一样,给a加上1后就赋值给了b。
c=a++代码:
[Asm] 纯文本查看 复制代码 1 2 3 4 | mov eax , DWORD PTR [ esp +0xc] 将a的值拷贝打 eax 寄存器
lea edx ,[ eax +0x1] 将 eax 加1后存入 edx 寄存器,此时 edx 的值为7
mov DWORD PTR [ esp +0xc], edx 再将 edx 的值拷贝给a
mov DWORD PTR [ esp +0x4], eax 将 eax 的值拷贝给 c
|
可以看到,先将a的值也就是6保存在eax寄存器中,然后将a的值加1,此时a已经是7了。但是赋给c的值却不是a,而是eax寄存器保存的值,也就是6。
d=a代码:
[Asm] 纯文本查看 复制代码 1 2 | mov eax , DWORD PTR [ esp +0xc] 将a的值拷贝到 eax 寄存器,注意此时a的值已经是7了
mov DWORD PTR [ esp ], eax 将 eax 的值拷贝给d,于是d的值是7
|
那么,最终运行结果是:
a==7;
b==6;
c==6;
d==7;
从上我们可以得出结论:
对于b=++a,编译器是将a加1后直接赋值给b
对于c=a++,编译器是先将a的值保存在一个临时变量中,本文是eax寄存器,然后将a加1,最后将临时变量的值赋值给c。结果就是c中是a原来的值,而a已经加了1。
实际上,c=a++等价于下面的代码:
|
免费评分
-
查看全部评分
|