Post

Instereing answer with gcc and clang compiler

Instereing answer with gcc and clang compiler

One day, My companion Tsai ask me a question,“do you know (++i)(++i)(++i) equal answer?”, Then i wrote a program for run.

    #include "stdio.h" 
    int main() {
    	int d=3;
    	printf("%d",(++i)+(++i)+(++i));
    	return 0;;
    }

I GOT TWO VALUE FOR ANSWER!!

GCC-7.4.0 COMPILER:

$: gcc 运算符和表达式.c && ./a.out

$:16

CLANG-8.1.0 COMPILER:

$: clang 运算符和表达式.c && ./a.out

$:15

so, I reversed code for analysis.

#reversed assembly(AT&T format)

$: objdump -d a.out > gcc.dmp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
000000000000064a <main>:
 64a:	55                   	push   %rbp      		  /赋值?/
 64b:	48 89 e5             	mov    %rsp,%rbp  		  /rsp,rbp为堆栈地址?/
 64e:	48 83 ec 10          	sub    $0x10,%rsp  		  /值为16/
 652:	c7 45 fc 03 00 00 00 	movl   $0x3,-0x4(%rbp)    /把i=3长字节放在rbp堆栈/
 659:	83 45 fc 01          	addl   $0x1,-0x4(%rbp)    /i=i+1放入rbp堆栈/
 65d:	83 45 fc 01          	addl   $0x1,-0x4(%rbp)    /i=i+1放入rbp堆栈,此时i=5/
 661:	8b 45 fc             	mov    -0x4(%rbp),%eax    /把rbp短字节(i=5)堆栈值,移动到寄存器ax/
 64a:	55                   	push   %rbp               /赋值?/
 64b:	48 89 e5             	mov    %rsp,%rbp          /rsp,rbp为堆栈地址?/
 64e:	48 83 ec 10          	sub    $0x10,%rsp         /值为16/
 652:	c7 45 fc 03 00 00 00 	movl   $0x3,-0x4(%rbp)    /把i=3长字节放在rbp堆栈/
 659:	83 45 fc 01          	addl   $0x1,-0x4(%rbp)    /i=i+1放入rbp堆栈/
 65d:	83 45 fc 01          	addl   $0x1,-0x4(%rbp)    /i=i+1放入rbp堆栈,此时i=5/
 661:	8b 45 fc             	mov    -0x4(%rbp),%eax    /把rbp短字节(i=5)堆栈值,移动到寄存器ax/
 664:	8d 14 00             	lea    (%rax,%rax,1),%edx /寄存器ax与寄存器ax相加放到寄存器dx/ /dx=10/
 667:	83 45 fc 01          	addl   $0x1,-0x4(%rbp)    /i=i+1=6放入rbp堆栈/
 66b:	8b 45 fc             	mov    -0x4(%rbp),%eax    /把结果i=6移动到寄存器ax/
 66e:	01 d0                	add    %edx,%eax          /把寄存器dx与寄存器ax相加,也就是10+6/
 670:	89 c6                	mov    %eax,%esi          /把16移动到寄存器si/
 672:	48 8d 3d 9b 00 00 00 	lea    0x9b(%rip),%rdi        # 714 <_IO_stdin_used+0x4>   /我也没看懂/   
 679:	b8 00 00 00 00       	mov    $0x0,%eax          /寄存器ax赋值/
 67e:	e8 9d fe ff ff       	callq  520 <printf@plt>   /调用函数printf/
 683:	b8 00 00 00 00       	mov    $0x0,%eax          /寄存器ax赋值/
 688:	c9                   	leaveq 
 689:	c3                   	retq 
 68a:	66 0f 1f 44 00 00    	nopw   0x0(%rax,%rax,1)  

the self-added operator seem not higher priority,it always self-add, and than register and register add.


Let’s see clang compiler

$: objdump -d a.out > clang.dmp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
0000000000400500 <main>:
  400500:	55                   	push   %rbp         	  /赋值?/
  400500:	55                   	push   %rbp               /赋值?/
  400501:	48 89 e5             	mov    %rsp,%rbp    
  400504:	48 83 ec 10          	sub    $0x10,%rsp
  400508:	48 bf e4 05 40 00 00 	movabs $0x4005e4,%rdi     
  40050f:	00 00 00 
  400512:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%rbp)     
  400519:	c7 45 f8 03 00 00 00 	movl   $0x3,-0x8(%rbp)
  400520:	8b 45 f8             	mov    -0x8(%rbp),%eax 
  400523:	83 c0 01             	add    $0x1,%eax          /寄存器ax +1,此时寄存器ax的i=4/
  400526:	89 45 f8             	mov    %eax,-0x8(%rbp)    /把i=i+1结果给rbp堆栈/
  400529:	8b 4d f8             	mov    -0x8(%rbp),%ecx    /把rbp堆栈赋值给寄存器cx,rbp堆栈的值为4/
  40052c:	83 c1 01             	add    $0x1,%ecx          /寄存器cx +1,此时寄存器cx的i=5/
  40052f:	89 4d f8             	mov    %ecx,-0x8(%rbp)    /寄存器cx值给rbp堆栈,rbp堆栈的值为5/
  400532:	01 c8                	add    %ecx,%eax          /寄存器ax与寄存器cx相加,4+5=9,寄存器ax为9/
  400534:	8b 4d f8             	mov    -0x8(%rbp),%ecx    /把rbp堆栈的值给寄存器cx,此时寄存器cx的值i=5/
  400537:	83 c1 01             	add    $0x1,%ecx          /寄存器cx +1,此时i=6/
  40053a:	89 4d f8             	mov    %ecx,-0x8(%rbp)    /寄存器cx值给rbp堆栈,rbp堆栈的值为6/
  40053d:	01 c8                	add    %ecx,%eax          /寄存器cx与寄存器ax相加,6+9=15/
  40053f:	89 c6                	mov    %eax,%esi          /寄存器ax值赋值到寄存器si/
  400541:	b0 00                	mov    $0x0,%al           /移动到寄存器al/
  400543:	e8 b8 fe ff ff       	callq  400400 <printf@plt>/调用fun函数printf/
  400548:	31 c9                	xor    %ecx,%ecx          /异或运算,cx与cx的值相同,结果为0/
  40054a:	89 45 f4             	mov    %eax,-0xc(%rbp)    /寄存器ax/
  40054d:	89 c8                	mov    %ecx,%eax          /寄存器cx的值给寄存器ax,结果是15/
  40054f:	48 83 c4 10          	add    $0x10,%rsp         /rsp堆栈为什么要填入10?/
  400553:	5d                   	pop    %rbp
  400554:	c3                   	retq   
  400555:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
  40055c:	00 00 00 
  40055f:	90                   	nop

The answer seems also correct, But I confuse what different from gcc and clang compiler…

#Conclusion

Seem gcc build less asm code than clang.

This post is licensed under CC BY 4.0 by the author.