现在基本上有了些眉目,我这边测试了O0,O1,O2,O3,Os优化等级,只有Os优化等级编译的代码能够正确运行,其他优化等级都出现崩溃打印信息。
通过反汇编分析,发现不同优化等级优化后二进制代码相差较大,但只有Os优化的代码调用了strcat函数,其他的优化等级(O0,O1,O2,O3)都没有调用strcat函数,被优化掉了。
下面附上c代码和Os、O1优化后的反汇编代码
原始c代码:
const char* finsh_get_prompt()
{
#define _MSH_PROMPT "msh "
#define _PROMPT "finsh "
static char finsh_prompt[RT_CONSOLEBUF_SIZE + 1] = {0};
#ifdef FINSH_USING_MSH
if (msh_is_used()) strcpy(finsh_prompt, _MSH_PROMPT);
else
#endif
strcpy(finsh_prompt, _PROMPT);
#ifdef DFS_USING_WORKDIR
/* get current working directory */
getcwd(&finsh_prompt[rt_strlen(finsh_prompt)], RT_CONSOLEBUF_SIZE - rt_strlen(finsh_prompt));
#endif
strcat(finsh_prompt, ">");
return finsh_prompt;
}
O1优化后的反汇编代码:
a00249b4
:
a00249b4: e92d4818 push {r3, r4, fp, lr}
a00249b8: e28db00c add fp, sp, #12
a00249bc: e59f307c ldr r3, [pc, #124] ; a0024a40
a00249c0: e59f207c ldr r2, [pc, #124] ; a0024a44
a00249c4: e8920003 ldm r2, {r0, r1}
a00249c8: e5830000 str r0, [r3]
a00249cc: e2833004 add r3, r3, #4
a00249d0: e1c310b0 strh r1, [r3]
a00249d4: e2833002 add r3, r3, #2
a00249d8: e1a02821 lsr r2, r1, #16
a00249dc: e5c32000 strb r2, [r3]
a00249e0: e59f0058 ldr r0, [pc, #88] ; a0024a40
a00249e4: ebff878f bl a0006828
a00249e8: e1a02000 mov r2, r0
a00249ec: e59f304c ldr r3, [pc, #76] ; a0024a40
a00249f0: e0824003 add r4, r2, r3
a00249f4: e59f0044 ldr r0, [pc, #68] ; a0024a40
a00249f8: ebff878a bl a0006828
a00249fc: e1a03000 mov r3, r0
a0024a00: e2633080 rsb r3, r3, #128 ; 0x80
a0024a04: e1a00004 mov r0, r4
a0024a08: e1a01003 mov r1, r3
a0024a0c: ebffc13e bl a0014f0c
a0024a10: e59f0028 ldr r0, [pc, #40] ; a0024a40
a0024a14: eb0047e5 bl a00369b0
a0024a18: e1a03000 mov r3, r0
a0024a1c: e1a02003 mov r2, r3
a0024a20: e59f3018 ldr r3, [pc, #24] ; a0024a40
a0024a24: e0823003 add r3, r2, r3
a0024a28: e59f2018 ldr r2, [pc, #24] ; a0024a48
a0024a2c: e1d220b0 ldrh r2, [r2]
a0024a30: e1c320b0 strh r2, [r3]
a0024a34: e59f3004 ldr r3, [pc, #4] ; a0024a40
a0024a38: e1a00003 mov r0, r3
a0024a3c: e8bd8818 pop {r3, r4, fp, pc}
a0024a40: a007922c andge r9, r7, ip, lsr #4
a0024a44: a0068ea4 andge r8, r6, r4, lsr #29
a0024a48: a0068eac andge r8, r6, ip, lsr #29
Os优化后的反汇编代码:
a0013cac
:
a0013cac: e92d4038 push {r3, r4, r5, lr}
a0013cb0: e59f403c ldr r4, [pc, #60] ; a0013cf4
a0013cb4: e59f103c ldr r1, [pc, #60] ; a0013cf8
a0013cb8: e1a00004 mov r0, r4
a0013cbc: eb00285d bl a001de38
a0013cc0: e1a00004 mov r0, r4
a0013cc4: ebffc073 bl a0003e98
a0013cc8: e1a05000 mov r5, r0
a0013ccc: e1a00004 mov r0, r4
a0013cd0: ebffc070 bl a0003e98
a0013cd4: e2601080 rsb r1, r0, #128 ; 0x80
a0013cd8: e0840005 add r0, r4, r5
a0013cdc: ebffdfe6 bl a000bc7c
a0013ce0: e1a00004 mov r0, r4
a0013ce4: e59f1010 ldr r1, [pc, #16] ; a0013cfc
a0013ce8: eb00272e bl a001d9a8
a0013cec: e1a00004 mov r0, r4
a0013cf0: e8bd8038 pop {r3, r4, r5, pc}
a0013cf4: a005c170 andge ip, r5, r0, ror r1
a0013cf8: a0050c1c andge r0, r5, ip, lsl ip
a0013cfc: a005086b andge r0, r5, fp, ror #16
通过上面的反汇编代码可以发现只有Os优化时,所有的newlib库函数都会被调用,其他的优化等级可能导致部分函数优化掉了。
我这边使用的编译器版本
gcc version 4.7.2 (Sourcery CodeBench Lite 2012.09-63)
gcc version 4.8.1 (Sourcery CodeBench Lite 2013.11-24)
难道是编译器本身的问题?
附崩溃信息:
\ | /
- RT - Thread Operating System
/ | \ 2.0.0 build Aug 27 2014
2006 - 2013 Copyright by rt-thread team
Execption:
r00:0x00000007 r01:0xa0079234 r02:0x0000003e r03:0xa0079233
r04:0xa0079232 r05:0x00000000 r06:0x00000000 r07:0x00000000
r08:0x00000000 r09:0x00000000 r10:0x00000000
fp :0xa0079200 ip :0x01010101
sp :0x00000000 lr :0x00000000 pc :0xa0024a38
cpsr:0x00000013
data abort
thread - tshell stack:
thread pri status sp stack size max used left tick error
-------- ---- ------- ---------- ---------- ---------- ---------- ---
tidle 0xff ready 0x00000044 0x00000100 0x00000044 0x00000020 000
timer 0x08 suspend 0x0000007c 0x00000200 0x0000007c 0x00000009 000
tshell 0x14 ready 0x00000044 0x00001000 0x00000084 0x0000000a 000
init 0x50 ready 0x00000044 0x00000800 0x00000044 0x00000014 000
shutdown...
这个崩溃信息是上面O1优化等级对应的代码产生的。