从反汇编看C++(一)

汇编较C++而言更为底层,虽然二者并无伯仲之分,但可以从汇编的角度更好的理解C++中的一些细节,同时也可以对C++进行反汇编了解汇编。

笔者在写文章时,开发工具用的是Microsoft Visual Studio 2012,系统类型是64为操作系统。

首先开门见山,看一个很简单的表达式热热身

int a = 1,b = 2;
a = a + b;
声明了两个变量a和b,将a和b相加并将结果保存在a中。我们查看它的反汇编代码

	int a = 1,b = 2;
008A4C3E  mov         dword ptr [a],1  
008A4C45  mov         dword ptr [b],2  
	a = a + b;
008A4C4C  mov         eax,dword ptr [a]  
008A4C4F  add         eax,dword ptr [b]  
008A4C52  mov         dword ptr [a],eax  
对于

int a = 1,b = 2;
汇编语言的处理是将数值1和2分别存储到内存位置a和b中

a = a + b;
在加法操作中用到了eax寄存器,因为在汇编语言中,内存为值不能向内存位置直接赋值,只能通过寄存器这个中间人将数据存储过去。闲话少说,首先,将内存位置a中的值存储到eax寄存器中,之后将内存位置b中的值和eax寄存器中的值相加并将结果存储会eax寄存器,最后将eax寄存器中的值存储到内存位置a中。

不知道大家感觉如何,反正我对于从这种视角看C++感觉挺有意思的。

下面我们看看可能是困扰很多C++初学者的自增问题

int a = 0;
int b = a++;
b = ++a;
我们来反汇编它

	int a = 0;
00F54C3E  mov         dword ptr [a],0  
	int b = a++;
00F54C45  mov         eax,dword ptr [a]  
00F54C48  mov         dword ptr [b],eax  
00F54C4B  mov         ecx,dword ptr [a]  
00F54C4E  add         ecx,1  
00F54C51  mov         dword ptr [a],ecx  
	b = ++a;
00F54C54  mov         eax,dword ptr [a]  
00F54C57  add         eax,1  
00F54C5A  mov         dword ptr [a],eax  
00F54C5D  mov         ecx,dword ptr [a]  
00F54C60  mov         dword ptr [b],ecx  
对于声明并初始化a为0的过程不必赘述,首先我们看第一条表达式

int b = a++;
我们按照顺序一条一条的读反汇编后的5条指令

第一步,内存地址a的值被存储在寄存器eax中。

第二步,寄存器eax中的值被存储在内存地址为b的位置上。

第三步,将内存地址a的值存储在ecx寄存器中。

第四步,将ecx寄存器中的值加1并且将结果存放回ecx寄存器中。

最后,将ecx寄存器中的值存放回内存地址a的位置上。

从上述过程,大家已经看到了,变量a的值先是赋给b,之后a再自加1。有些读者可能会疑惑为什么第四步不直接把eax寄存器中的值加1而非要将a重新放到ecx中一次,再对ecx加1?这里反汇编主要考虑的是不对寄存器造成内容上的冲突,CPU内部寄存器很多,有查看eax寄存器中的值是不是我刚才存放的,倒不如重新放到新的寄存器中进行计算来的方便。毕竟人家是机器,不能和我们发达的人脑相比。大笑

接下来我们看第二条表达式

b = ++a;
同样我们还是一条一条得看,不过这次,我们和第一条表达式的反汇编结果进行找不同

我们看到第一步和最后一步都是一样的,分别是将a放入eax寄存器中和将ecx寄存器中的结果放到b中。

中间的步骤顺序发生了改变,首先,eax寄存器中存储的变量a的值加1并存回eax寄存器中,然后,eax寄存器中的值被存储到内存位置a中,最后,ecx寄存器作为中间的存储a的值。

这条语句,变量a先自加,然后将结果赋值给变量b。前置和后置自增操作符也曾经困扰过刚接触编程的笔者,就和当年学英语分不清楚positive和negative哪一个是积极的一样。微笑


今天先写到这里,如有不足之处请各位多加品评。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值