c语言printf("%d %d",i++,i++)和printf("%d %d",++i,++i)

我们看一下反汇编的代码;

1、

printf("%d %d",i++,i++)
反汇编之后

   0x0040150e <+14>:movl   $0x0,0x1c(%esp)
   0x00401516 <+22>:mov    0x1c(%esp),%edx
   0x0040151a <+26>:lea    0x1(%edx),%eax
   0x0040151d <+29>:mov    %eax,0x1c(%esp)
   0x00401521 <+33>:mov    0x1c(%esp),%eax
   0x00401525 <+37>:lea    0x1(%eax),%ecx
   0x00401528 <+40>:mov    %ecx,0x1c(%esp)
   0x0040152c <+44>:mov    %edx,0x8(%esp)
   0x00401530 <+48>:mov    %eax,0x4(%esp)
   0x00401534 <+52>:movl   $0x404000,(%esp)
   0x0040153b <+59>:call   0x402618 <printf>
我们有看到,当i最开始放在存在于寄存器edx和栈0x1c(%esp)这个两个地方,也就是0,然后i++之后,值放在寄存器eax为1和栈0x1c(%esp)(此时栈0x1c(%esp)处值为1),然后继续i++之后,值放在寄存器ecx为2和栈0x1c(%esp)(此时栈0x1c(%esp)处值为2),然后通过将寄存器edx为0放在0x8(%esp),eax为1放在0x4(%esp)中;至此,栈中的值从高地址往底地址为2,0,1;

movl   $0x404000,(%esp)
,然后调用printf函数打印栈,则为1,0;

2、

printf("%d %d",++i,++i)
我们继续反汇编:

   0x0040150e <+14>:movl   $0x0,0x1c(%esp)
   0x00401516 <+22>:addl   $0x1,0x1c(%esp)
   0x0040151b <+27>:addl   $0x1,0x1c(%esp)
   0x00401520 <+32>:mov    0x1c(%esp),%eax
   0x00401524 <+36>:mov    %eax,0x8(%esp)
   0x00401528 <+40>:mov    0x1c(%esp),%eax
   0x0040152c <+44>:mov    %eax,0x4(%esp)
   0x00401530 <+48>:movl   $0x404000,(%esp)
   0x00401537 <+55>:call   0x402608 <printf>
我么可以清除的看到,其连续执行了两次加一操作,数据放在栈0x1c(%esp)处,然后0x1c(%esp)复制给eax和0x8(%esp)、0x4(%esp),也就是2;然后

movl   $0x404000,(%esp)
,继而执行打印操作,我们知道栈中此时的数据为2,2,2;则打印为2,2;

综上,经过上面的过程我们可以看到,i++先输出再执行加操作,,++i先执行加操作然后输出;

然后楼上说的“这种代码不易读,而且容易犯错,编译器的不同会导致答案的不同~“这句话是有道理的,编辑器不同,汇编代码会有差别,导致标准输出结果会有所偏差,不建议这么用,除了考试,我想没有其他人会这么用了。

上一篇: 串口的问题
下一篇: 这是最新的一篇日志
文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags:
相关日志:
评论: 0 | 引用: 0 | 查看次数: -
发表评论
昵 称:
密 码: 游客发言不需要密码.
邮 箱: 邮件地址支持Gravatar头像,邮箱地址不会公开.
网 址: 输入网址便于回访.
内 容:
验证码:
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.
字数限制 1000 字 | UBB代码 开启 | [img]标签 关闭