GCC的优化选项,可以加速我们的程序,使程序执行效率更高。但是,倘若我们就是需要程序慢一点运行,但是优化却把我们的延时函数优化的没有了的时候,这种优化却不是我们想要的。有时候,我们需要事物差的一面。下边的代码是我的 main.c 程序。
#include <stdio.h>
void wait(unsigned long dly)
{
for(; dly> 0; dly--);
}
int main(void)
{
while(1){
printf("hello!\n");
wait(30000);
}
return 0;
}
一、使用默认选项编译
1、编译
gcc main.c -o main
2、查看汇编文件
生成反汇编代码:
objdump -s -d main > main.txt
查看反汇编代码:
0000000000001149 <wait>:
1149: f3 0f 1e fa endbr64
114d: 55 push %rbp
114e: 48 89 e5 mov %rsp,%rbp
1151: 48 89 7d e8 mov %rdi,-0x18(%rbp)
1155: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
115c: eb 04 jmp 1162 <wait+0x19>
115e: 83 45 fc 01 addl $0x1,-0x4(%rbp)
1162: 48 83 7d e8 00 cmpq $0x0,-0x18(%rbp)
1167: 75 f5 jne 115e <wait+0x15>
1169: 48 83 6d e8 01 subq $0x1,-0x18(%rbp)
116e: 90 nop
116f: 5d pop %rbp
1170: c3 ret
0000000000001171 <main>:
1171: f3 0f 1e fa endbr64
1175: 55 push %rbp
1176: 48 89 e5 mov %rsp,%rbp
1179: 48 8d 05 84 0e 00 00 lea 0xe84(%rip),%rax # 2004 <_IO_stdin_used+0x4>
1180: 48 89 c7 mov %rax,%rdi
1183: e8 c8 fe ff ff call 1050 <puts@plt>
1188: bf 30 75 00 00 mov $0x7530,%edi
118d: e8 b7 ff ff ff call 1149 <wait>
1192: eb e5 jmp 1179 <main+0x8>
二、添加优化
1、编译
gcc -O2 main.c -o main
2、查看汇编代码
生成反汇编代码:
objdump -s -d main > main.txt
查看汇编代码:
...
0000000000001060 <main>:
1060: f3 0f 1e fa endbr64
1064: 53 push %rbx
1065: 48 8d 1d 98 0f 00 00 lea 0xf98(%rip),%rbx # 2004 <_IO_stdin_used+0x4>
106c: 0f 1f 40 00 nopl 0x0(%rax)
1070: 48 89 df mov %rbx,%rdi
1073: e8 d8 ff ff ff call 1050 <puts@plt>
1078: eb f6 jmp 1070 <main+0x10>
107a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
...
0000000000001170 <wait>:
1170: f3 0f 1e fa endbr64
1174: c3 ret
可以看到,我们的延时函数完全被优化的没有了,那么我们的延时函数还有什么用。
三、问题分析
wait函数中的等待是一个空操作
void wait(unsigned long dly)
{
while(dly)
dly--;
}
void wait(unsigned long dly)
{
for(int i= dly; i > 0; i--);
dly--;
}
都会被优化掉。
加上关键字volatile就可以告诉编译器,不用优化,而是在内存中读取dly的值
void wait(unsigned long dly)
{
while(volatile dly)
dly--;
}