代码如下: 1. #include 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" 3. .LC0: 4. .string "%d n" 5. .text 6. .globl main 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等,结果让我想起大学学习《计算机组成原理与接口》时,见过循环位移和算术位移。可以这么理解在没有优化的结果是循环位移。 优化的结果是算术位移。
|