分类: LINUX
2013-09-27 10:26:40
代码如下:
1. #include <stdio.h>
2.
3. int main()
4. {
5. int i = 1;
6.
7. i <<= 32;
8.
9. printf("i = %d \n", i);
10. return 0;
11. }
编译与运行:
1. $gcc test.c -o test
2. $test
3. 1
在32位机器上,这个结果是错误。因为在32位机器上如果1左移32就变成0了。在优化版的结果是正确的。
优化的编译与运行:
1. $gcc test.c -o test
2. $test
3. 0
1. 1
在32位机器上,这个结果是错误。因为在32位机器上如果1左移32就变成0了。在优化版的结果是正确的。
优化的编译与运行:
1. $gcc test.c -o test
2. $test
3. 0
接着分析:
转换成asm
1. gcc -S test.c
转化出来为:
1. .file "t4.c"
2. .section .rodata
3. .LC0:
4. .string "%d \n"
5. .text
6. .globl main
7. .type main, @function
8. main:
9. pushl %ebp
10. movl %esp, %ebp
11. andl $-16, %esp
12. subl $32, %esp
13. movl $1, 28(%esp)
14. movl $32, %ecx
15. sall %cl, 28(%esp)
16. movl $.LC0, %eax
17. movl 28(%esp), %edx
18. movl %edx, 4(%esp)
19. movl %eax, (%esp)
20. call printf
21. movl $0, %eax
22. leave
23. ret
24. .size main, .-main
25. .ident "GCC: (GNU) 4.5.1 20100924 (Red Hat 4.5.1-4)"
26. .section .note.GNU-stack,"",@progbits
优化的转换成asm
1. gcc -S -O2 test.c
转化后为:
1. .file "t4.c"
2. .section .rodata.str1.1,"aMS",@progbits,1
3. .LC0:
4. .string "%d \n"
5. .text
6. .p2align 4,,15
7. .globl main
8. .type main, @function
9. main:
10. pushl %ebp
11. movl %esp, %ebp
12. andl $-16, %esp
13. subl $16, %esp
14. movl $0, 4(%esp)
15. movl $.LC0, (%esp)
16. call printf
17. xorl %eax, %eax
18. leave
19. ret
20. .size main, .-main
21. .ident "GCC: (GNU) 4.5.1 20100924 (Red Hat 4.5.1-4)"
22. .section .note.GNU-stack,"",@progbits
其中最主要的区别是,没有优化的有sall,而优化过的没有。看看sall指令到底是怎么做的就了了。
在试试其他的数字,比如说31,33等,结果让我想起大学学习《计算机组成原理与接口》时,见过循环位移和算术位移。可以这么理解在没有优化的结果是循环位移。
优化的结果是算术位移。