在中断程序内 变量的加加,这种情况是否会出现BUG!

2019-12-27 19:02发布

先说明一下   a=a+1这条程序语句的执行步骤:
javascript:;

我在想这种情况:
如果执行到第一步,将a的值读到寄存器R中

执行完这一条后,来了个中断就是 a=a-1 !
等执行完 a=a-1 ,这时候重点来了!

我的CPU会回到 a=a+1 的第二步!
R寄存器里面是不知道 a 已经被改变了,所以他还是按照原先的值 加1!
然后在写回到 a !
  
这时候就会出现bug了!
这种情况大伙们有考虑过吗?  要怎么避免?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
84条回答
落叶知秋
1楼-- · 2020-01-03 23:58
以前调程序就遇到过这样的BUG,是这样的:

  1. //中断里:
  2. write();
  3. count++;

  4. //后台里:
  5. if(count)
  6. {
  7.   read();
  8.   count--;//如果这里中断来了就出问题了,count的值不会不变,而会-1,总数不对
  9.              //中断越频繁,越大几率出现这个BUG
  10. }
复制代码

后来是加了锁,特殊处理一下才没问题。
片羽之神
2楼-- · 2020-01-04 00:00
 精彩回答 2  元偷偷看……
yoursnemo
3楼-- · 2020-01-04 05:48
laoshuhunya 发表于 2016-12-6 22:45
8位机也是一样的问题。
这个帖子生动地说明了搞嵌入式不了解汇编是行不通的
                 ...

嗯嗯,汇编还是相当重要的。看到下面redroof的回复,也意识到8位机也有这种问题的存在。单单靠现场保护也不够。
jm2011
4楼-- · 2020-01-04 08:29
这个问题是基本功哈,LZ提出的问题是在中断中,其实不光在中断,在多线程里,异步函数里面都有这样的问题;区别主要是中断不能被锁死(锁死了机器就挂了);

另外,许多人对LZ提出的问题不太理解, 看看 a++ 产生的指令就知道:
[a++]:
lw $8, [a]
add $8, $8, 1
sw $8, [a]

至少三条指令,这三条指令的序列被打断后对地址[a]进行修改都会造成错误结果;对8位机需要多个读-修改-写操作,但是本质还是一样的;
zhugean
5楼-- · 2020-01-04 11:31
如果指令系统不支持原子操作的话,就要手动处理
knight_sh
6楼-- · 2020-01-04 17:10
落叶知秋 发表于 2016-12-7 09:07
以前调程序就遇到过这样的BUG,是这样的:

建议用生产消费模型,也就是中断内维护一个wr,任务里维护一个rd,if(wr != rd)表明有新的事件

一周热门 更多>