Chinaunix首页 | 论坛 | 博客
  • 博客访问: 300270
  • 博文数量: 148
  • 博客积分: 4365
  • 博客等级: 上校
  • 技术积分: 1566
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-05 21:38
文章分类
文章存档

2014年(2)

2013年(45)

2012年(18)

2011年(1)

2009年(54)

2008年(28)

我的朋友

分类: C/C++

2009-09-15 13:24:12

本页题目来自于网络http://blog.chinaunix.net/u/25675/showart_254804.html
其余出自本人键盘。
更新:eclipse所用的MinGW中GDB调试时为反汇编,缺少了许多语句,应用
gcc -S test.cpp 产生test.s完整汇编文件,故本文某些内容正确性值得商榷

在windows下
,写出运行结果,说明为什么?

int arr[]={6,7,8,9,10};
int *ptr=arr;
*(ptr++)+=123;
printf("%d,%d",*ptr,*(++ptr));
printf(" %d,%d",*ptr,*(ptr++));

奇怪了,eclipse结果:8,8 9,8
VC6结果            8,8 8,8
VS2005结果        
8,8 8,8
再看题目要求,在windows下,莫非有些猫腻不成。我的eclipse是windows下的,用的MinGW,模拟的GCC,看来Windows和Linux参数处理不太一样,
看看汇编,VC6的,intel型汇编

9: int arr[]={6,7,8,9,10};
0040D708 mov dword ptr [ebp-14h],6
0040D70F mov dword ptr [ebp-10h],7
0040D716 mov dword ptr [ebp-0Ch],8
0040D71D mov dword ptr [ebp-8],9
0040D724 mov dword ptr [ebp-4],0Ah
10: int *ptr=arr;
0040D72B lea eax,[ebp-14h]
0040D72E mov dword ptr [ebp-18h],eax
11: *(ptr++)+=123;
0040D731 mov ecx,dword ptr [ebp-18h]
0040D734 mov edx,dword ptr [ecx]
0040D736 add edx,7Bh
0040D739 mov eax,dword ptr [ebp-18h]
0040D73C mov dword ptr [eax],edx
0040D73E mov ecx,dword ptr [ebp-18h]
0040D741 add ecx,4
0040D744 mov dword ptr [ebp-18h],ecx
12: printf("%d,%d",*ptr,*(++ptr));
0040D747 mov edx,dword ptr [ebp-18h]
0040D74A add edx,4
0040D74D mov dword ptr [ebp-18h],edx
0040D750 mov eax,dword ptr [ebp-18h]
0040D753 mov ecx,dword ptr [eax]
0040D755 push ecx
0040D756 mov edx,dword ptr [ebp-18h]
0040D759 mov eax,dword ptr [edx]
0040D75B push eax
0040D75C push offset string "%d,%d" (00422fb4)
0040D761 call printf (00401060)
0040D766 add esp,0Ch
13: printf(" %d,%d",*ptr,*(ptr++));
0040D769 mov ecx,dword ptr [ebp-18h]
0040D76C mov edx,dword ptr [ecx]
0040D76E mov dword ptr [ebp-1Ch],edx
0040D771 mov eax,dword ptr [ebp-1Ch]
0040D774 push eax
0040D775 mov ecx,dword ptr [ebp-18h]
0040D778 mov edx,dword ptr [ecx]
0040D77A push edx
0040D77B push offset string " %d,%d" (00422fac)
0040D780 mov eax,dword ptr [ebp-18h]
0040D783 add eax,4
0040D786 mov dword ptr [ebp-18h],eax
0040D789 call printf (00401060)
0040D78E add esp,0Ch
14: printf("\nHello World!\n");
0040D791 push offset string "\nHello World!\n" (0042201c)
0040D796 call printf (00401060)
0040D79B add esp,4

在第二个printf处,的确可以看到,先将两个参数入栈后再对指针ptr加4(整形指针)

看看MinGW汇编,AT&T型的

    int arr[]={6,7,8,9,10};
0x00401525 <main+21>: movl $0x7,0xffffffdc(%ebp)
0x00401536 <main+38>: movl $0x8,0xffffffe0(%ebp)
0x0040153d <main+45>: movl $0x9,0xffffffe4(%ebp)
0x00401544 <main+52>: movl $0xa,0xffffffe8(%ebp)
    *(ptr++)+=123;
0x0040154b <main+59>: movl $0x81,0xffffffd8(%ebp)
    printf("%d,%d",*ptr,*(++ptr));
0x0040152c <main+28>: push %eax
0x0040152d <main+29>: push $0x8
0x0040152f <main+31>: push $0x8
0x00401531 <main+33>: push $0x4014e9
0x00401552 <main+66>: call 0x415220 <printf>
    printf(" %d,%d",*ptr,*(ptr++));
0x00401557 <main+71>: mov 0xffffffe4(%ebp),%edx
0x0040155a <main+74>: add $0xc,%esp
0x0040155d <main+77>: mov 0xffffffe0(%ebp),%ecx
0x00401560 <main+80>: push %ecx
0x00401561 <main+81>: push %edx
0x00401562 <main+82>: push $0x4014ef
0x00401567 <main+87>: call 0x415220 <printf>

第一个printf处,保存EAX寄存器后,直接压入两个常数8作为参数,而第二个printf压入的参数是两个间接寻址的操作数,第一个push %ecx,而ecx中是mov 0xffffffe0(%ebp),%ecx,即为[ebp+0xffffffe0],对照前五行汇编,是8,第二个push %edx,其中是,mov 0xffffffe4(%ebp),%edx,是9,而C++参数入栈从右向左,所以输出顺序为 9,8.
多说一句,不知汇编产生和编译器的具体联系,但产生AT&T型的挺厉害,在*(ptr++)+=123;语句后,才对*ptr处赋值 0x81,即十进制129,初值6加该语句加值123


第二题在windows下,写出运行结果,说明为什么?

int arr[]={6,7,8,9,10};
int *ptr=arr;
*(ptr++)=*(ptr++)+123;
printf("%d,%d",*ptr,*(++ptr))

eclipse与VC6均为9,9
先看MinGW汇编

    int arr[]={6,7,8,9,10};
0x00401515 <main+21>: movl $0x7,0xffffffdc(%ebp)
0x00401526 <main+38>: movl $0x8,0xffffffe0(%ebp)
0x0040152d <main+45>: movl $0x9,0xffffffe4(%ebp)
0x00401534 <main+52>: movl $0xa,0xffffffe8(%ebp)
    *(ptr++)=*(ptr++)+123;
0x0040153b <main+59>: movl $0x81,0xffffffd8(%ebp)
    printf("%d,%d",*ptr,*(++ptr));
0x0040151c <main+28>: push %edx
0x0040151d <main+29>: push $0x9
0x0040151f <main+31>: push $0x9
0x00401521 <main+33>: push $0x4014e9
0x00401542 <main+66>: call 0x415200 <printf>

直接就是两个常数9入栈

VC6汇编

9: int arr[]={6,7,8,9,10};
0040D708 mov dword ptr [ebp-14h],6
0040D70F mov dword ptr [ebp-10h],7
0040D716 mov dword ptr [ebp-0Ch],8
0040D71D mov dword ptr [ebp-8],9
0040D724 mov dword ptr [ebp-4],0Ah
10: int *ptr=arr;
0040D72B lea eax,[ebp-14h]
0040D72E mov dword ptr [ebp-18h],eax
11: *(ptr++)=*(ptr++)+123;
0040D731 mov ecx,dword ptr [ebp-18h]
0040D734 mov edx,dword ptr [ecx]
0040D736 add edx,7Bh
0040D739 mov eax,dword ptr [ebp-18h]
0040D73C mov dword ptr [eax],edx
0040D73E mov ecx,dword ptr [ebp-18h]
0040D741 add ecx,4
0040D744 mov dword ptr [ebp-18h],ecx
0040D747 mov edx,dword ptr [ebp-18h]
0040D74A add edx,4
0040D74D mov dword ptr [ebp-18h],edx
12: printf("%d,%d",*ptr,*(++ptr));
0040D750 mov eax,dword ptr [ebp-18h]
0040D753 add eax,4
0040D756 mov dword ptr [ebp-18h],eax
0040D759 mov ecx,dword ptr [ebp-18h]
0040D75C mov edx,dword ptr [ecx]
0040D75E push edx
0040D75F mov eax,dword ptr [ebp-18h]
0040D762 mov ecx,dword ptr [eax]
0040D764 push ecx
0040D765 push offset string "%d,%d" (00422fac)
0040D76A call printf (00401060)
0040D76F add esp,0Ch

看来对于++或--前缀没有任何疑问,差别就在于后缀
阅读(430) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~