首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Keil uVision5 armcc.exe: if语句中无符号短裤的问题不能正常工作?

Keil uVision5 armcc.exe: if语句中无符号短裤的问题不能正常工作?
EN

Stack Overflow用户
提问于 2021-02-19 07:47:42
回答 1查看 29关注 0票数 0

armcc.exe V5.06 (750)请告诉我为什么一旦val16溢出并变得比start_count小,标记为有故障的代码就不能工作。循环不再退出。

HAL_GetTick()返回uint32_t (或int)

代码语言:javascript
复制
unsigned short start_count;

unsigned short val16;
unsigned short result;

start_count = HAL_GetTick(); 

//This does not work
do
{
    val16 = HAL_GetTick();
    result = val16 - start_count;
}
while ((val16 - start_count)  < 100);  //this part does not work correctly 
                                       //when val16 overflows

//This works!  same code logic
do
{
    val16 = HAL_GetTick();
    result = val16 - start_count;
}
while (result  < 100);

`

EN

回答 1

Stack Overflow用户

发布于 2021-02-19 08:07:24

首先,不要在没有特殊需要的情况下使用较短的类型,因为这通常会增加32位RISC目标的额外开销。

第一个while不起作用,因为算术是使用int完成的,而不是无符号的短值,从而产生意外的结果:)。这里有一个演示程序:

代码语言:javascript
复制
unsigned HAL_GetTick(void)
{
    static unsigned tick = 65535 - 5;
    return tick++;
}

int main(void)
{
    unsigned short val16;
    unsigned short result;
    unsigned short start_count;

    start_count = HAL_GetTick(); 

    //This does not work
    do
    {
        val16 = HAL_GetTick();
        result = val16 - start_count;
        printf("%d %d\n", (val16 - start_count)  < 100, (val16 - start_count));
    }
    while ((val16 - start_count)  < 100);  //this part does not work correctly 
                                        //when val16 overflows

    //This works!  same code logic
    do
    {
        val16 = HAL_GetTick();
        result = val16 - start_count;
    }
    while (result  < 100);
}

https://godbolt.org/z/fa5M7W

第二个循环使用无符号短类型,并且在计算result时不会隐式转换该类型。

https://godbolt.org/z/6TshP8

现在,使用ARM Cortex内核的非本机整数的问题。

示例程序:

代码语言:javascript
复制
volatile uint32_t tick;

uint32_t HAL_GetTick(void)
{
    return tick;
}

void foo(void)
{
    unsigned short val16;
    unsigned short result;
    unsigned short start_count;

    start_count = HAL_GetTick(); 


    //This works!  same code logic
    do
    {
        val16 = HAL_GetTick();
        result = val16 - start_count;
    }
    while (result  < 100);
}

void bar(void)
{
    uint32_t val16;
    uint32_t result;
    uint32_t start_count;

    start_count = HAL_GetTick(); 


    //This works!  same code logic
    do
    {
        val16 = HAL_GetTick();
        result = val16 - start_count;
    }
    while (result  < 100);
}

以及生成的代码:

代码语言:javascript
复制
foo:
        ldr     r1, .L9
        ldr     r2, [r1]
        lsl     r2, r2, #16
        lsr     r2, r2, #16
.L6:
        ldr     r3, [r1]
        sub     r3, r3, r2
        lsl     r3, r3, #16
        lsr     r3, r3, #16
        cmp     r3, #99
        bls     .L6
        bx      lr
.L9:
        .word   tick
bar:
        ldr     r2, .L15
        ldr     r1, [r2]
.L12:
        ldr     r3, [r2]
        sub     r3, r3, r1
        cmp     r3, #99
        bls     .L12
        bx      lr
.L15:
        .word   tick

正如您所看到的,使用16位整数的版本比使用32位本机大小整数的版本效率要低。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66269808

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档