代码跑飞的问题
本文是原「蜗窝讨论区」的历史存档(2017-01-17),来自版块「Linux kernel技术问答」,共 4 帖。讨论区已停止服务,此处仅供查阅。
遇到代码偶尔跑飞的问题,跑飞的位置看不出什么规律,很难下手,下面是一个例子:
[== Undefined ==]
......
mDelay(1);
/* send this info to indicate the start of comunicaton */
for(i=0; i<7; i++)
sysPutChar(chk_start[i], WB_UART_1);
.......
这段代码sysPutChar只发了一个字节,之后就没有反应了,作如下修改:
[== Undefined ==]
.......
mDelay(1);
/* send this info to indicate the start of comunicaton */
for(i=0; i<7; i++)
sysPutChar(chk_start[i], WB_UART_1);
asm volatile("nop":::"memory");
.......
加了一条空指令就正常运行,不是sysPutChar的问题,因为其他地方有的时候也会出现类似现象,反汇编如下,看不出什么问题 1401bc4: e3a00001 mov r0, #1 1401bc8: ebfff956 bl 1400128 <mDelay> 1401bcc: e3a03000 mov r3, #0 1401bd0: ea000007 b 1401bf4 <check_board_valid+0x40> 1401bd4: e59d1010 ldr r1, 1401bd8: e59f21e8 ldr r2, ; 1401dc8 <check_board_valid+0x214> 1401bdc: e0820001 add r0, r2, r1 1401be0: e5d00063 ldrb r0, [r0, #99] ; 0x63 1401be4: e3a01001 mov r1, #1 1401be8: eb0017c5 bl 1407b04 <sysPutChar> 1401bec: e59d3010 ldr r3, 1401bf0: e2833001 add r3, r3, #1 1401bf4: e58d3010 str r3, 1401bf8: e59dc010 ldr ip, 1401bfc: e35c0006 cmp ip, #6 1401c00: 9afffff3 bls 1401bd4 <check_board_valid+0x20> 1401c04: e1a00000 nop ; (mov r0, r0)
没有调试器,不知道代码运行的情况,请教大家,有没有什么调试方向?
空指令 换成 mdelay 是不是也可以执行成功啊
感觉应该是Optimization barrier的问题。 这里关键不是那一条空指令,而是volatile和clobber list中的“memory”这个关键字。
我们知道,嵌入式汇编的语法格式是:asm(code : output operand list : input operand list : clobber list)。clober list是gcc和gas的接口,用于gas通知gcc它对寄存器和memory的修改情况。因此,这里的memory就是告知gcc,在汇编代码中,我修改了memory中的内容,嵌入式汇编之前的c代码块和嵌入式汇编之后的c代码块看到的memory是不一样的,对memory的访问不能依赖于嵌入式汇编之前的c代码块中寄存器的内容,需要重新加载。
因此,我的想法是:插入asm volatile("nop":::"memory");后,你的代码被分成两段:
A 段代码 asm volatile("nop":::"memory"); B 段代码
gcc在编译这样的代码的时候,A和B段代码不会因为优化而mix。
我的一点想法,仅供参考。
谢谢回复
最开始也考虑过屏障的影响,但是对照过两个版本的反汇编文件,指令顺序是一样的,所以应该不是这个原因,其实添加其他代码也一样,另外出现问题的时候arm没有发生异常
