当 IAR MSP430 编译器中的优化设置为高时,会发生指令的疯狂执行

发布于 2024-11-11 14:54:08 字数 1325 浏览 3 评论 0原文

请参考我下面的代码。当 IAR MSP430 编译器中的优化设置为高时,我遇到以下问题。当优化程度较低时,代码可以正常工作。

问题:如果 (B) 处的条件语句返回 false,则执行语句 (A) 而不是语句 (C)。

int16_t cpu_flash_read_setting (void * setting, const uint8_t offset, const uint8_t num_of_bytes)
{
    int16_t returnable_status = PASS;
    uint16_t flash_copy_one_address =  FLASH_INFO_SEG_C_ADDR + offset;
    uint16_t flash_copy_two_address =  FLASH_INFO_SEG_D_ADDR + offset;
    if (0U == (num_of_bytes % sizeof(uint16_t))) 
    {
        uint16_t *setting_copy_one = (uint16_t *) flash_copy_one_address;
        uint16_t *setting_copy_two = (uint16_t *) flash_copy_two_address;  
        if (*setting_copy_one == *setting_copy_two)
        {
            setting = setting_copy_one;       
        }
        else
        {
(A)         returnable_status = FAIL;         
        }
    }
    else if (0U == (num_of_bytes % sizeof(uint8_t))) 
    {
        uint8_t *setting_copy_one = (uint8_t *) flash_copy_one_address;
        uint8_t *setting_copy_two = (uint8_t *) flash_copy_two_address;  
(B)     if (*setting_copy_one == *setting_copy_two)
        {
            setting = setting_copy_one;       
        }
        else
        {
(C)        returnable_status = FAIL;         
        }      
    }
    else
    {
        /* No Action */
    }
    return returnable_status;    
}

Please refer to my code below. When optimization in IAR MSP430 compiler is set high, I am having the following issue. Code works fine when optimization is low.

Issue: If the condition statement at (B) returns false, statement (A) is executed instead of statement (C).


int16_t cpu_flash_read_setting (void * setting, const uint8_t offset, const uint8_t num_of_bytes)
{
    int16_t returnable_status = PASS;
    uint16_t flash_copy_one_address =  FLASH_INFO_SEG_C_ADDR + offset;
    uint16_t flash_copy_two_address =  FLASH_INFO_SEG_D_ADDR + offset;
    if (0U == (num_of_bytes % sizeof(uint16_t))) 
    {
        uint16_t *setting_copy_one = (uint16_t *) flash_copy_one_address;
        uint16_t *setting_copy_two = (uint16_t *) flash_copy_two_address;  
        if (*setting_copy_one == *setting_copy_two)
        {
            setting = setting_copy_one;       
        }
        else
        {
(A)         returnable_status = FAIL;         
        }
    }
    else if (0U == (num_of_bytes % sizeof(uint8_t))) 
    {
        uint8_t *setting_copy_one = (uint8_t *) flash_copy_one_address;
        uint8_t *setting_copy_two = (uint8_t *) flash_copy_two_address;  
(B)     if (*setting_copy_one == *setting_copy_two)
        {
            setting = setting_copy_one;       
        }
        else
        {
(C)        returnable_status = FAIL;         
        }      
    }
    else
    {
        /* No Action */
    }
    return returnable_status;    
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

零崎曲识 2024-11-18 14:54:08

在我看来这完全合理。当您将优化调高时,编译器可以而且通常会疯狂地重新排序语句。除了类型之外,您的两个主要子句是相同的 - 因此编译器完全有可能合并执行路径并让它们仅在实际重要的地方有所不同。

只有当实际可观察​​到的效果与预期效果不同时,这才是一个问题。

无论如何,优化的代码总是很难用调试器来跟踪,正是因为重新排序的影响。

顺便说一句,如果您的代码正在与实际硬件通信,您可能需要将 flash_copy_*_address 变量声明为 易失性。这向编译器暗示,它们指向的内存不一定以正常方式运行,并迫使编译器在优化时更加保守。

That looks entirely reasonable to me. When you have optimisation turned up high, the compiler can and usually will re-order statements wildly. Your two main clauses are identical apart from their typing - so it's entirely plausible for the compiler to merge the execution paths and have them differ only where it actually matters.

This is only a problem if the actual observable effect differs from what was intended.

In any event, optimised code is always difficult to follow with a debugger, precisely because of the re-ordering effects.

By the way, if your code is talking to actual hardware you may want to declare the flash_copy_*_address variables as volatile. This is a hint to the compiler that the memory they point to doesn't necessarily behave in the normal way, and forces it be more conservative with its optimisations.

灯角 2024-11-18 14:54:08

两行代码 AC 是相同的,执行路径在这两行之后合并(两种情况下要执行的下一行都是 return returnable_status 因此,

编译器正在执行尾部合并优化,对两个源代码行使用相同的汇编代码块。这种优化是预期的并且完全有效,并且不会引起问题。

The two lines of code A and C are identical, and the execution paths merge after those two lines (the next line to be executed in both cases is return returnable_status;.

Thus the compiler is performing tail-merging optimisation, using the same block of assembly code for both source code lines. This optimisation is expected and perfectly valid, and should not cause a problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文