警惕arm-linux-gcc编译器优化选项
arm-linux-gcc的优化选项例如(-O2),可以加速我们的程序,使程序执行效率更高。但是,倘若我们就是需要程序慢一点运行,但是优化却把我们的延时函数优化的没有了的时候,这种优化却不是我们想要的。有时候,我们需要事物差的一面。下边的代码是我的main.c程序。
#define GPBCON (*(volatile unsigned long *)0x56000010)
#define GPBDAT (*(volatile unsigned long *)0x56000014)
#define GPB5_out (1<<(5*2))
#define GPB6_out (1<<(6*2))
#define GPB7_out (1<<(7*2))
#define GPB8_out (1<<(8*2))
void wait(unsigned long dly)
{
for(; dly > ; dly--);
}
int main(void)
{
unsigned long i = ;
GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out; // 将LED1-4对应的GPB5/6/7/8四个引脚设为输出
while(){
wait();
GPBDAT = (~(i<<)); // 根据i的值,点亮LED1-4
if(++i == ){
i = ;
}
}
return ;
}
这部分程序使用优化选项(-O2)编译的,编译后的汇编程序如下所示。
0000001c <wait>:
1c: e12fff1e bx lr
<main>:
: e92d4010 stmdb sp!, {r4, lr}
: e3a03b55 mov r3, # ; 0x15400
: e3a04456 mov r4, # ; 0x56000000
2c: e59f0060 ldr r0, [pc, #] ; 94 <.text+0x94>
: e5843010 str r3, [r4, #]
: ebfffff8 bl 1c <wait>
: e3e03000 mvn r3, # ; 0x0
3c: e59f0050 ldr r0, [pc, #] ; 94 <.text+0x94>
: e5843014 str r3, [r4, #]
: ebfffff4 bl 1c <wait>
: e3e03020 mvn r3, # ; 0x20
4c: e5843014 str r3, [r4, #]
: e59f003c ldr r0, [pc, #] ; 94 <.text+0x94>
: ebfffff0 bl 1c <wait>
: e3e03040 mvn r3, # ; 0x40
5c: e3a01003 mov r1, # ; 0x3
: e5843014 str r3, [r4, #]
: e1a04001 mov r4, r1
: e59f0024 ldr r0, [pc, #] ; 94 <.text+0x94>
6c: ebffffea bl 1c <wait>
: e2841001 add r1, r4, # ; 0x1
: e1a03284 mov r3, r4, lsl #
: e1e03003 mvn r3, r3
7c: e3a02456 mov r2, # ; 0x56000000
: e3510010 cmp r1, # ; 0x10
: e5823014 str r3, [r2, #]
: e3a04000 mov r4, # ; 0x0
8c: 1afffff4 bne <main+0x44>
: eafffff4 b <main+0x48>
: andeq r7, r0, r0, lsr r5
可以看到,我们的延时函数完全被优化的没有了,那么我们的延时函数还有什么用。实验现象是这个流水灯已经完全看不出来流动,而是全亮,由于流动的太快人眼无法识别以至于看不出来流动了。
现在,我把优化选项(-O2)去掉,再来看一下反汇编代码。
0000001c <wait>:
1c: e24dd008 sub sp, sp, #8 ; 0x8
20: e58d0004 str r0, [sp, #4]
24: ea000002 b 34 <wait+0x18>
28: e59d3004 ldr r3, [sp, #4]
2c: e2433001 sub r3, r3, #1 ; 0x1
30: e58d3004 str r3, [sp, #4]
34: e59d3004 ldr r3, [sp, #4]
38: e3530000 cmp r3, #0 ; 0x0
3c: 1afffff9 bne 28 <wait+0xc>
40: e28dd008 add sp, sp, #8 ; 0x8
44: e12fff1e bx lr
<main>:
: e52de004 str lr, [sp, #-]!
4c: e24dd00c sub sp, sp, # ; 0xc
: e3a03000 mov r3, # ; 0x0
: e58d3004 str r3, [sp, #]
: e59f2048 ldr r2, [pc, #] ; a8 <.text+0xa8>
5c: e3a03b55 mov r3, # ; 0x15400
: e5823000 str r3, [r2]
: eaffffff b <main+0x20>
: e59f003c ldr r0, [pc, #] ; ac <.text+0xac>
6c: ebffffea bl 1c <wait>
: e59f2038 ldr r2, [pc, #] ; b0 <.text+0xb0>
: e59d3004 ldr r3, [sp, #]
: e1a03283 mov r3, r3, lsl #
7c: e1e03003 mvn r3, r3
: e5823000 str r3, [r2]
: e59d3004 ldr r3, [sp, #]
: e2833001 add r3, r3, # ; 0x1
8c: e58d3004 str r3, [sp, #]
: e59d3004 ldr r3, [sp, #]
: e3530010 cmp r3, # ; 0x10
: 1afffff2 bne <main+0x20>
9c: e3a03000 mov r3, # ; 0x0
a0: e58d3004 str r3, [sp, #]
a4: eaffffef b <main+0x20>
a8: undefined
ac: andeq r7, r0, r0, lsr r5
b0: undefined
这时,我们可以看到延时函数被完整的保存下来了。当然实验现象中,我们也可以看出来流水灯的流动。
说明一点,当程序出现意想不到的情况时,可以通过反汇编来查看问题的原因。
警惕arm-linux-gcc编译器优化选项的更多相关文章
- Ubuntu12.4 64位 安装 arm linux gcc 4.3.2
一.下载arm linux gcc 4.3.2 http://pan.baidu.com/share/link?shareid=1575352696&uk=2754759285&fid ...
- gcc编译器优化给我们带来的麻烦???
gcc编译器优化给我们带来的麻烦??? 今天看到一个很有趣的程序,如下: ? 1 2 3 4 5 6 7 8 9 int main() { const int a = 1; int * ...
- gcc编译器常用选项的含义
-w: 关闭编译时的警告, 也就是编译后不显示任何warning,因此有时编译中会出现一些诸如数据转换之类的可忽略警告, -Wall: 显示编译后所有警告 -W: 显示警告,但是只是显示编译器认为的会 ...
- <转载>linux gcc编译器中使用gdb单步调试程序,程序不是顺序执行的。
原文地址http://blog.csdn.net/abc78400123/article/details/6779108 在用gdb调试,使用s 或n单步执行程序时,发现程序不是按顺序运行的,有时莫名 ...
- Linux gcc编译器
GNU CC(通常称为GCC)是GNU项目的编译器,他能够编译C.C++语言编写的程序. 使用gcc,程序员可以对编译过程有更多控制,编译过程分为3个阶段. --预处理 --汇编 --链接 程序员可以 ...
- gcc O2优化选项对内嵌汇编以及函数递归调用的影响
学习和使用c这些年来,很多方面都未深入研究过,就如脱离了IDE后,我可能连编译一个c文件的命令都写不出来. 最近需要在c中内嵌汇编解决问题,参考网上相关的资料写了一段汇编代码,在测试的时候时好时坏,找 ...
- 测试gcc的优化选项
一.测试准备及原理 测试代码: static void wait(volatile unsigned long dly) { ; dly--); } int main(void) { unsigned ...
- 【转】C 编译器优化过程中的 Bug
C 编译器优化过程中的 Bug 一个朋友向我指出一个最近他们发现的 GCC 编译器优化过程(加上 -O3 选项)里的 bug,导致他们的产品出现非常诡异的行为.这使我想起以前见过的一个 GCC bug ...
- gcc 优化选项 -O1 -O2 -O3 -Os 优先级
http://hi.baidu.com/xiaole10368/item/7cea9b1369cc240db88a1a5c 少优化->多优化: O0 -->> O1 -->&g ...
随机推荐
- Redis学习手册(虚拟内存)
一.简介: 和大多NoSQL数据库一样,Redis同样遵循了Key/Value数据存储模型.在有些情况下,Redis会将Keys/Values保存在内存中以提高数据查询和数据修改的效率,然而这样的做法 ...
- cglib源码分析(一): 缓存和KEY
cglib是一个java 字节码的生成工具,它是对asm的进一步封装,提供了一系列class generator.研究cglib主要是因为它也提供了动态代理功能,这点和jdk的动态代理类似. 一. C ...
- Android5.0之Activity的转场动画
Activity的转场动画很早就有,但是太过于单调,样式也不好看,于是Google在Android5.0之后,又推出的新的转场动画,效果还是非常炫的,今天我们一起来看一下. 1.旧转场动画回顾 首先我 ...
- 利用C语言强行点击置灰的按钮
通常很多情况下,会有这样的事情,就是: 我们在运行某些程序的时候,发现按钮置灰了,比如购买版权或者输入序列号才能够获得访问权限.某个按钮才允许点击. 其实所有的这些东西都是 别的人或者公司利用一些编程 ...
- Linux Bash终端支持中文显示
方法:修改系统变量LANG 即时生效: LANG=en_US.UTF- 永久生效: 修改.bashrc,加入 fi
- java.sql.SQLException: Before start of result set
在使用JDBC查询数据库报了这么一个错误 CREATE TABLE `d_user` ( `id` int(10) NOT NULL, `name` varchar(10) DEFAULT NULL, ...
- PHP 获取当前日期的上个月的日期
获取当前日期的上个月的日期 <?php /** *参考有: *http://www.oschina.net/code/snippet_96541_4015 *http://stackoverfl ...
- 推荐几个对Asp.Net开发者比较实用的工具
推荐几个对Asp.Net开发者比较实用的工具.大家有相关工具也可以在评论区留言,一起努力学习. 工具 1.Visual stdio Productivity Power tool:visual std ...
- IIS限制ASP.Net 文件上传大小解决方案,修改IIS7/7.5配置
当在web.config中设置了 httpruntime 后还是无法成功上传大文件,则要修改IIS的系统config IIS 7 默认文件上传大小是30M 要突破这个限制: 修改IIS的applica ...
- c编程:提示用户输入一个0—9的数字进行猜测电脑产生的随机数。一共有三次机会。
// // main.c // 使用c语言进行编程: 题目:由电脑生成一个由0-9之间的随机数,提示用户也输入一个数字进行猜测.当猜测三次仍不中的时候结束程序. 编译环境:Xcode6.3 特别介 ...