C语言的怪异题

 1.
int a=10;
a=(a++ )* 2;

2.
volatile int a=10;
a=(a++ )* 2;


我觉得在a=(a++)*2有两个关键点:
1、自增和乘法是每次从内存中取操作数,还是从寄存器中取操作数
2、a++中的赋值运行符,和表达式中出现的那个"=" 赋值运算符哪个在先

用R1,R2代表寄存器, a 代表变量的内存地址,把表达式展开如下:
x86:
情况1:
a = a*2
a = a + 1(结果为21)

情况2:
R1 = a
R2 = R1 * 2
a = R2
R2 = R1 + 1
a = R2 (结果为11)

arm:(两种情况相同)
R1 = a
R2 = R1
R2 = R2*2
a = R2
R1 = R1 + 1
a = R1 (结果为11)

ppc:(两种情况相同)
R1 = a
R2 = R1
R1 = R1*2
R0 = R0 + 1
a = R0
a = R1
a = R2 (结果为20)
结论:
a = (a++)*2这个表达式中的两个赋值运算符的先后顺序是混乱的。在这一个表达式中出现多次内存访问,变量值是否每次都要从内存中取值,也是依赖于不同平台,似乎RISC不会每次都去内存中取操作数。

附:
arm汇编
83b4: e3a0300a mov r3, #10 ; 0xa
83b8: e50b3010 str r3, [fp, -#16]
83bc: e24b1010 sub r1, fp, #16 ; 0x10
83c0: e5912000 ldr r2, [r1]
83c4: e1a03002 mov r3, r2
83c8: e1a03083 mov r3, r3, lsl #1
83cc: e50b3010 str r3, [fp, -#16]
83d0: e2822001 add r2, r2, #1 ; 0x1
83d4: e5812000 str r2, [r1]
83d8: e3a0300a mov r3, #10 ; 0xa
83dc: e50b3014 str r3, [fp, -#20]
83e0: e24b1014 sub r1, fp, #20 ; 0x14
83e4: e5912000 ldr r2, [r1]
83e8: e1a03002 mov r3, r2
83ec: e1a03083 mov r3, r3, lsl #1
83f0: e50b3014 str r3, [fp, -#20]
83f4: e2822001 add r2, r2, #1 ; 0x1
83f8: e5812000 str r2, [r1]

ppc汇编:
100004f8: 38 00 00 0a li r0,10
100004fc: 90 1f 00 08 stw r0,8(r31)
10000500: 81 3f 00 08 lwz r9,8(r31)
10000504: 7d 20 4b 78 mr r0,r9
10000508: 54 00 08 3c rlwinm r0,r0,1,0,30
1000050c: 39 29 00 01 addi r9,r9,1
10000510: 91 3f 00 08 stw r9,8(r31)
10000514: 90 1f 00 08 stw r0,8(r31)
10000518: 38 00 00 0a li r0,10
1000051c: 90 1f 00 0c stw r0,12(r31)
10000520: 39 7f 00 0c addi r11,r31,12
10000524: 81 2b 00 00 lwz r9,0(r11)
10000528: 7d 20 4b 78 mr r0,r9
1000052c: 54 00 08 3c rlwinm r0,r0,1,0,30
10000530: 39 29 00 01 addi r9,r9,1
10000534: 91 2b 00 00 stw r9,0(r11)
10000538: 90 1f 00 0c stw r0,12(r31)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值