: ret
0x00001f10 : push %ebp
0x00001f11 : mov %esp,%ebp
0x00001f13 : sub $0x28,%esp
0x00001f16 : mov 0xc(%ebp),%eax
0x00001f19 : mov 0x8(%ebp),%ecx
0x00001f1c : movl $0x0,-0x4(%ebp)
0x00001f23 : mov %ecx,-0x8(%ebp)
0x00001f26 : mov %eax,-0xc(%ebp)
0x00001f29 : movl $0x1,-0x10(%ebp)
0x00001f30 : xor %dl,%dl
0x00001f32 : test %dl,%dl
0x00001f34 : jne 0x1f52
0x00001f36 : jmp 0x1f38
0x00001f38 : lea 0x1fa0,%eax
0x00001f3e : mov -0x14(%ebp),%ecx
0x00001f41 : mov %eax,(%esp)
0x00001f44 : mov %ecx,0x4(%esp)
0x00001f48 : call 0x1f7a
0x00001f4d : mov %eax,-0x18(%ebp)
0x00001f50 : jmp 0x1f6a
0x00001f52 : lea 0x1fa0,%eax
0x00001f58 : mov -0x14(%ebp),%ecx
0x00001f5b : mov %eax,(%esp)
0x00001f5e : mov %ecx,0x4(%esp)
0x00001f62 : call 0x1f7a
0x00001f67 : mov %eax,-0x1c(%ebp)
0x00001f6a : mov $0x0,%eax
0x00001f6f : add $0x28,%esp
0x00001f72 : pop %ebp
0x00001f73 : ret
注意main+36和main + 38位置的汇编,两条跳转语句会直接找到标号,忽略了前面的代码。
如果把源代码改为如下,依然不能输出3:
[cpp]
int main(int argc, char **argv)
{
int a = 2;
switch(a)
{
int b = 2;
case 1:
PRINT_D(b)
break;
b = 3;
case 2:
PRINT_D(b)
break;
default:
PRINT_D(b)
break;
}
return 0;
}
int main(int argc, char **argv)
{
int a = 2;
switch(a)
{
int b = 2;
case 1:
PRINT_D(b)
break;
b = 3;
case 2:
PRINT_D(b)
break;
default:
PRINT_D(b)
break;
}
return 0;
}
Q4: sizeof运算符里面跟着i++,为什么i没有自增?
[cpp]
#include
#define PRINT_D(intValue) printf(#intValue" is %d\n", (intValue));
int main(int argc, char **argv)
{
int i = 1;
PRINT_D(sizeof(i++))
PRINT_D(i)
return 0;
}
#include
#define PRINT_D(intValue) printf(#intValue" is %d\n", (intValue));
int main(int argc, char **argv)
{
int i = 1;
PRINT_D(sizeof(i++))
PRINT_D(i)
return 0;
}
A: 原因在于sizeof在编译期间自动计算出来它的数值,对于i++, 编译器仅仅看到了它的类型,却没有计算它的数值。看看汇编:
[cpp]
0x00001ef0 : push %ebp
0x00001ef1 : mov %esp,%ebp
0x00001ef3 : push %ebx
0x00001ef4 : push %edi
0x00001ef5 : push %esi
0x00001ef6 : sub $0x2c,%esp
0x00001ef9 : mov 0xc(%ebp),%eax
0x00001efc : mov 0x8(%ebp),%ecx
0x00001eff : mov $0x0,%edx
0x00001f04 : lea 0x1fa7,%esi
0x00001f0a : lea 0x1f94,%edi
0x00001f10 : mov $0x4,%ebx
0x00001f15 : movl $0x0,-0x10(%ebp)
0x00001f1c : mov %ecx,-0x14(%ebp)
0x00001f1f : mov %eax,-0x18(%ebp)
0x00001f22 : movl $0x1,-0x1c(%ebp)
0x00001f29 : mov %edi,(%esp)
0x00001f2c : movl $0x4,0x4(%esp)
0x00001f34 : mov %edx,-0x20(%ebp)
0x00001f37 : mov %ebx,-0x24(%ebp)
0x00001f3a : mov %esi,-0x28(%ebp)
0x00001f3d : call 0x1f6e
0x00001f42 : mov -0x1c(%ebp),%ecx
0x00001f45 : mov -0x28(%ebp),%edx
0x00001f48 : mov %edx,(%esp)
0x00001f4b : mov %ecx,0x4(%esp)
0x00001f4f : mov %eax,-0x2c(%ebp)
0x00001f52 : call 0x1f6e
0x00001f57 : mov -0x20(%ebp),%ecx
0x00001f5a : mov %eax,-0x30(%ebp)
0x00001f5d : mov %ecx,%eax
0x00001f5f : add $0x2