憨厚的豌豆荚 2024-07-10 11:30 采纳率: 0%
浏览 22
已结题

keil中语句顺序影响结果

使用keil4编程,在串口中断中,其实就是简单的赋值语句

        if((T35_Delay2)&&(MB_Rx_First2==0))//接收开始
        {
            MB_Rcv_Cnt2 = 0;
            MB_Rx_First2 = 1;    
            MB_Rx_Buff2[MB_Rcv_Cnt2] = msg;                
        }

按照上面的写法,MB_Rcv_Cnt2每次不被清零。然后将MB_Rcv_Cnt2 = 0;移到下一行就正常了


```c
        if((T35_Delay2)&&(MB_Rx_First2==0))//接收开始
        {            
            MB_Rx_First2 = 1;
            MB_Rcv_Cnt2 = 0;
            MB_Rx_Buff2[MB_Rcv_Cnt2] = msg;                
        }

实在不明白为什么,有没有什么思路呢?调试方法?
看了disassembly窗口也看不出什么区别

img

  • 写回答

2条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-07-10 11:30
    关注

    引自免费微信小程序:皆我百晓生

    这个问题看起来是因为在编译器或汇编器的优化顺序问题导致的。由于现代处理器允许同时处理并行任务,例如在串口中断时同时执行多个操作,可能会影响到代码的执行顺序。尽管在高级语言(如C语言)中,代码是按照从上到下的顺序执行的,但在底层汇编代码中,处理器可能以不同的方式执行这些指令。

    在你给出的代码中,MB_Rx_First2 = 1 这句实际上比 MB_Rcv_Cnt2 = 0 更早执行。这意味着在进入中断时就已经更新了 MB_Rx_First2 的值。如果将 MB_Rx_First2 = 1 移动到 MB_Rcv_Cnt2 = 0 后面,就相当于在设置 MB_Rx_First2 的值之后才初始化 MB_Rcv_Cnt2,这样在中断期间就能确保按照预期的顺序执行操作。同时这也涉及到编译器优化和硬件执行顺序的问题。对于这种问题,可以尝试以下调试方法:

    1. 查看汇编代码: 你已经提到了查看disassembly窗口,这是一个很好的开始。可以检查指令间的执行顺序以及它们是否满足你的预期。但需要注意,有时即使看到汇编代码也不能完全理解其行为,因为涉及到处理器的具体实现和状态。
    2. 断点调试: 使用Keil的调试工具在特定的代码行设置断点,逐步执行并观察变量的状态变化。通过这种方式可以更好地理解程序的流程,看看实际运行时的执行顺序。这也有助于确认变量和标志是如何变化的。
    3. 简化代码: 如果可能的话,尝试简化代码结构,只保留关键部分进行调试。这样可以更容易地识别问题所在。例如,可以先只处理中断的部分,并添加足够的日志输出以观察变量值的变化。一旦找到了问题的原因,就可以将其他部分的代码逐渐加入回去。
    4. 检查其他可能的干扰因素: 确保没有其他部分的代码(如其他中断或并行运行的线程)可能会干扰到预期的执行顺序或改变变量的值。确保变量的可见性和可访问性符合期望,特别是在多线程环境中。

    关于你提供的汇编代码图(图1),由于它涉及到具体的汇编指令和硬件寄存器操作,解析起来相对复杂。从提供的汇编代码来看,其中涉及到很多硬件寄存器的直接操作和数据在内存中的布局问题,这些因素都可能导致指令执行顺序和预期的不一致。这也是为什么更改语句顺序能够影响结果的原因。解决这类问题通常需要深入理解底层硬件和汇编语言的知识,以及具体的编译器优化行为。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 7月10日
  • 创建了问题 7月10日