有关printf多个输出时的输出问题

vs中的printf


最近有位兄弟在群里发了这样一个问题

在这里插入图片描述
我开始没意识过来,后来自己算了一遍,算出为“3 6”,这问题就有点大了,开始百度吧。
查了一圈,发现了第一个问题,printf的计算顺序是从右往左的(和栈有关,先入后出),于是再次计算,发现还是不对,第二次算出为“4 2”。所有又是哪里出问题了呢。
忽然想起,vs有反汇编的功能,那我直接看汇编代码看看问题出在哪
(vs的编译器是cl,不同编译器将会有不同结果)
在这里插入图片描述
嗯,主体部分都在这,我们一条一条看

	char a = 1;
004018E8  mov         byte ptr [a],1	 ;把立即数1送到a所指向的地址单元(一个字节),ptr表示指针,也就是给变量a赋值
	printf("%d %d", a += 2, a *= 2);	 
004018EC  movsx       eax,byte ptr [a]   ;将变量a的值赋给eax寄存器
004018F0  shl         eax,1  			 ;eax寄存器左移一位,也就是a*2
004018F2  mov         byte ptr [a],al  	 ;al表示eax寄存器的低八位,是最低的八位,eax为32位的,这句的意思是把eax的值又赋给a
004018F5  movsx       ecx,byte ptr [a]   ;a的值赋给ecx寄存器
004018F9  add         ecx,2  			 ;a+2
004018FC  mov         byte ptr [a],cl  	 ;a=a+2,给a赋值,这是变量a就是4了,同理cl为ecx的低八位
004018FF  movsx       edx,byte ptr [a]   ;a的值赋给edx寄存器,为4
00401903  push        edx  				 ;将edx的内容压栈
00401904  movsx       eax,byte ptr [a]   
;问题出在这句,本来在这句代码之前,eax的内容为2;即第一个算式a*=2的内容;这里重新赋值,导致eax变成了4,下图为单步执行时寄存器值的变化
00401908  push        eax  				 ;将eax的内容压栈
	printf("%d %d", a += 2, a *= 2);
00401909  push        offset string "%d %d" (0407B30h)  
0040190E  call        _printf (040104Bh)  
00401913  add         esp,0Ch  

在这里插入图片描述
在这里插入图片描述
至此,我们可以从汇编代码中可以看出“4 4”结果整个的计算过程

群里大佬的总结:(对应开始时输出两次变量a的值)
在这里插入图片描述
在这里插入图片描述
最后验证了一下,确实是从右到左算完后,再从左到右输出

(小弟俺第一次使用vs的反汇编动能,也没接触过cl的汇编程序,如有错误恳请纠正)

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值