搜索
bottom↓
回复: 15

STM32中的if语句判断32位变量不正确

[复制链接]

出590入992汤圆

发表于 2018-1-11 17:16:03 | 显示全部楼层 |阅读模式
本帖最后由 SUPER_CRJ 于 2018-1-12 11:14 编辑

使用芯片STM32F10X系列时,发现下列问题:
        typedef union
        {
                u8 IndexLen8[2048]; // 可正常读出,不可写入
                u16 IndexLen16[1024];  // 1024个16位
        }_Flash_High_Density_TypeDef;
#define HighDensity_FlashPage(x)    ((_Flash_High_Density_TypeDef *) (0x08000000+x*0x800))
#define L_APP_SIZE_H                      HighDensity_FlashPage(6)->IndexLen16[1]   // 这个的值为:0xFFFF
#define L_APP_SIZE_L                      HighDensity_FlashPage(6)->IndexLen16[2]    // 这个的值为:0xFFFF

#define STM32FlashMemorySize ( ( unsigned short int *) (0x1FFFF7E0))  // 这个指针值是:64

发现:使用下面语句,出的结果是我想要的。也就是会retrun FAIL
if( (u32)(( L_APP_SIZE_H<<16 ) + L_APP_SIZE_L ) >=  (u32)( (*STM32FlashMemorySize)*1024 ) )  //
        {
                return FAIL;  
        }
但是:使用下面,就不会
if( (( L_APP_SIZE_H<<16 ) + L_APP_SIZE_L ) >=  ( (*STM32FlashMemorySize)*1024 ) )  //
        {
                return FAIL;  
        }
这是为什么?

最新结果:谢谢大家,就是符号位的问题,也感谢shangdawei的编译器解析,因为没有加强制转换默认为有符号数:于是0xFFFFFFFF这个数,实际上就是最小的有符号的数,而程序的本意是无符号的判断

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出40入42汤圆

发表于 2018-1-11 17:33:02 | 显示全部楼层
符号问题?

出0入0汤圆

发表于 2018-1-11 18:08:26 | 显示全部楼层
如果 L_APP_SIZE_H<<16的值默认类型是int,并且最高位是1,就变成负数了吧?

出0入0汤圆

发表于 2018-1-11 18:50:55 | 显示全部楼层
隐式类型转换的问题,用到的立即数最好指定类型。

出0入0汤圆

发表于 2018-1-11 17:16:04 | 显示全部楼层
if( (u32)(( L_APP_SIZE_H<<16 ) + L_APP_SIZE_L ) >=  (u32)( (*STM32FlashMemorySize)*1024 ) )  

使用无符号数比较指令:BCC/BLO/BCS/BHS/BHI/BLS
        CMP      R1,R2
        BCC.N    ??foo_1  // 小于(无符号数)

if( (( L_APP_SIZE_H<<16 ) + L_APP_SIZE_L ) >=  ( (*STM32FlashMemorySize)*1024 ) )

使用有符号数比较指令:BLT/BLE/BGT/BGE

        CMP      R1,R2
        BLT.N    ??foo_3 // 小于(有符号数)

出0入0汤圆

发表于 2018-1-11 21:54:49 | 显示全部楼层
  1. #include <stdint.h>
  2. #define FAIL 0UL
  3. #define SUCCESS 1UL
  4. typedef uint8_t u8;
  5. typedef uint16_t u16;
  6. typedef uint32_t u32;

  7. typedef union
  8. {
  9.   u8 IndexLen8[ 2048 ];      // 可正常读出,不可写入
  10.   u16 IndexLen16[ 1024 ];    // 1024个16位
  11. } _Flash_High_Density_TypeDef;

  12. #define HighDensity_FlashPage( x ) ( ( _Flash_High_Density_TypeDef * ) ( 0x08000000 + x * 0x800 ) )
  13. #define L_APP_SIZE_H HighDensity_FlashPage( 6 )->IndexLen16[ 1 ]    // 这个的值为:0xFFFF
  14. #define L_APP_SIZE_L HighDensity_FlashPage( 6 )->IndexLen16[ 2 ]    // 这个的值为:0xFFFF

  15. #define STM32FlashMemorySize ( ( unsigned short int * ) ( 0x1FFFF7E0 ) )    // 这个指针值是:64

  16. u32 foo( void )
  17. {
  18.   if ( ( u32 )( ( L_APP_SIZE_H << 16 ) + L_APP_SIZE_L ) >= ( u32 )( ( *STM32FlashMemorySize ) * 1024 ) )    //
  19.   {
  20.     return FAIL;
  21.   }

  22.   if ( ( ( L_APP_SIZE_H << 16 ) + L_APP_SIZE_L ) >= ( ( *STM32FlashMemorySize ) * 1024 ) )    //
  23.   {
  24.     return FAIL;
  25.   }

  26.   if ( ( u32 )( ( L_APP_SIZE_H << 16 ) + L_APP_SIZE_L ) >= ( ( *STM32FlashMemorySize ) * 1024 ) )    //
  27.   {
  28.     return FAIL;
  29.   }

  30.   if ( ( ( L_APP_SIZE_H << 16 ) + L_APP_SIZE_L ) >= ( u32 )( ( *STM32FlashMemorySize ) * 1024 ) )    //
  31.   {
  32.     return FAIL;
  33.   }

  34.   return SUCCESS;
  35. }
复制代码

出0入0汤圆

发表于 2018-1-11 21:56:09 | 显示全部楼层

        #define SHT_PROGBITS 0x1

        PUBLIC foo

//    1 #include <stdint.h>
//    2 #define FAIL 0UL
//    3 #define SUCCESS 1UL
//    4 typedef uint8_t u8;
//    5 typedef uint16_t u16;
//    6 typedef uint32_t u32;
//    7
//    8 typedef union
//    9 {
//   10   u8 IndexLen8[ 2048 ];      // @@@@@@@@@@@@@@@
//   11   u16 IndexLen16[ 1024 ];    // 1024@?6@
//   12 } _Flash_High_Density_TypeDef;
//   13
//   14 #define HighDensity_FlashPage( x ) ( ( _Flash_High_Density_TypeDef * ) ( 0x08000000 + x * 0x800 ) )
//   15 #define L_APP_SIZE_H HighDensity_FlashPage( 6 )->IndexLen16[ 1 ]    // @@@@@@@@@?xFFFF
//   16 #define L_APP_SIZE_L HighDensity_FlashPage( 6 )->IndexLen16[ 2 ]    // @@@@@@@@@?xFFFF
//   17
//   18 #define STM32FlashMemorySize ( ( unsigned short int * ) ( 0x1FFFF7E0 ) )    // @@@@@@@@@@?4
//   19

        SECTION `.text`:CODE:NOROOT(2)
        THUMB
//   20 u32 foo( void )
//   21 {
//   22   if ( ( u32 )( ( L_APP_SIZE_H << 16 ) + L_APP_SIZE_L ) >= ( u32 )( ( *STM32FlashMemorySize ) * 1024 ) )    //
foo:
        LDR.N    R0,??foo_0       ;; 0x8003002
        LDRH     R0,[R0, #+0]
        UXTH     R0,R0            ;; ZeroExt  R0,R0,#+16,#+16
        LSLS     R0,R0,#+16
        LDR.N    R1,??foo_0+0x4   ;; 0x8003004
        LDRH     R1,[R1, #+0]
        UXTAH    R1,R0,R1
        LDR.N    R0,??foo_0+0x8   ;; 0x1ffff7e0
        LDRH     R2,[R0, #+0]
        UXTH     R2,R2            ;; ZeroExt  R2,R2,#+16,#+16
        MOV      R0,#+1024
        MULS     R2,R0,R2
        CMP      R1,R2
        BCC.N    ??foo_1
//   23   {
//   24     return FAIL;
        MOVS     R0,#+0
        B.N      ??foo_2
//   25   }
//   26
//   27   if ( ( ( L_APP_SIZE_H << 16 ) + L_APP_SIZE_L ) >= ( ( *STM32FlashMemorySize ) * 1024 ) )    //
??foo_1:
        LDR.N    R0,??foo_0       ;; 0x8003002
        LDRH     R0,[R0, #+0]
        UXTH     R0,R0            ;; ZeroExt  R0,R0,#+16,#+16
        LSLS     R0,R0,#+16
        LDR.N    R1,??foo_0+0x4   ;; 0x8003004
        LDRH     R1,[R1, #+0]
        UXTAH    R1,R0,R1
        LDR.N    R0,??foo_0+0x8   ;; 0x1ffff7e0
        LDRH     R2,[R0, #+0]
        UXTH     R2,R2            ;; ZeroExt  R2,R2,#+16,#+16
        MOV      R0,#+1024
        MULS     R2,R0,R2
        CMP      R1,R2
        BLT.N    ??foo_3
//   28   {
//   29     return FAIL;
        MOVS     R0,#+0
        B.N      ??foo_2
//   30   }
//   31
//   32   if ( ( u32 )( ( L_APP_SIZE_H << 16 ) + L_APP_SIZE_L ) >= ( ( *STM32FlashMemorySize ) * 1024 ) )    //
??foo_3:
        LDR.N    R0,??foo_0       ;; 0x8003002
        LDRH     R0,[R0, #+0]
        UXTH     R0,R0            ;; ZeroExt  R0,R0,#+16,#+16
        LSLS     R0,R0,#+16
        LDR.N    R1,??foo_0+0x4   ;; 0x8003004
        LDRH     R1,[R1, #+0]
        UXTAH    R1,R0,R1
        LDR.N    R0,??foo_0+0x8   ;; 0x1ffff7e0
        LDRH     R2,[R0, #+0]
        UXTH     R2,R2            ;; ZeroExt  R2,R2,#+16,#+16
        MOV      R0,#+1024
        MULS     R2,R0,R2
        CMP      R1,R2
        BCC.N    ??foo_4
//   33   {
//   34     return FAIL;
        MOVS     R0,#+0
        B.N      ??foo_2
//   35   }
//   36
//   37   if ( ( ( L_APP_SIZE_H << 16 ) + L_APP_SIZE_L ) >= ( u32 )( ( *STM32FlashMemorySize ) * 1024 ) )    //
??foo_4:
        LDR.N    R0,??foo_0       ;; 0x8003002
        LDRH     R0,[R0, #+0]
        UXTH     R0,R0            ;; ZeroExt  R0,R0,#+16,#+16
        LSLS     R0,R0,#+16
        LDR.N    R1,??foo_0+0x4   ;; 0x8003004
        LDRH     R1,[R1, #+0]
        UXTAH    R1,R0,R1
        LDR.N    R0,??foo_0+0x8   ;; 0x1ffff7e0
        LDRH     R2,[R0, #+0]
        UXTH     R2,R2            ;; ZeroExt  R2,R2,#+16,#+16
        MOV      R0,#+1024
        MULS     R2,R0,R2
        CMP      R1,R2
        BCC.N    ??foo_5
//   38   {
//   39     return FAIL;
        MOVS     R0,#+0
        B.N      ??foo_2
//   40   }
//   41
//   42   return SUCCESS;
??foo_5:
        MOVS     R0,#+1
??foo_2:
        BX       LR               ;; return
        DATA
??foo_0:
        DC32     0x8003002
        DC32     0x8003004
        DC32     0x1ffff7e0
//   43 }

        SECTION `.iar_vfe_header`:DATA:NOALLOC:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
        DC32 0

        END

出0入20汤圆

发表于 2018-1-11 22:00:03 | 显示全部楼层
输出预处理文件直接看到底什么类型,那一堆宏谁有心情慢慢看。。。

出0入0汤圆

发表于 2018-1-12 10:58:21 | 显示全部楼层
(( L_APP_SIZE_H<<16 ) + L_APP_SIZE_L )是有符号的,所以它是-1,所以不行

出0入0汤圆

发表于 2018-1-12 11:01:33 | 显示全部楼层
stm32是32位的,所以默认整型提升是int型,是有符号的

出0入0汤圆

发表于 2018-1-12 11:11:58 | 显示全部楼层
在C语言中,当一个无符号数和一个有符号数进行比较运算时,有符号数会被隐含的转换成无符号数,并假设这两个数都是非负数,然后进行比较运算。

出590入992汤圆

 楼主| 发表于 2018-1-12 11:16:36 | 显示全部楼层
shangdawei 发表于 2018-1-12 11:11
在C语言中,当一个无符号数和一个有符号数进行比较运算时,有符号数会被隐含的转换成无符号数,并假设这两 ...

谢谢~干货,昨天就是卡在这里,一时没想起来~下次比对的时候,还是小心比较好

出10入95汤圆

发表于 2018-1-14 12:15:46 来自手机 | 显示全部楼层
shangdawei 发表于 2018-1-12 11:11
在C语言中,当一个无符号数和一个有符号数进行比较运算时,有符号数会被隐含的转换成无符号数,并假设这两 ...

C基础不错哦!

出0入0汤圆

发表于 2020-10-17 15:54:15 | 显示全部楼层
赞一下,再细看

出0入54汤圆

发表于 2020-10-19 10:15:07 | 显示全部楼层
st 公司用arm公司cpu内核做芯片 ;1 ARM公司专业设计CPU  既然敢卖 至少是指令系统设计完善,所有指令执行不能错。ST做芯片敢卖 肯定保证芯片下线后内部不能有短路断路等等缺陷。而你编程序使用C语言,当年敢发明C语言的丹尼斯里奇和肯汤姆逊肯定能保证他们设计的C语言能够确定的编译成汇编语言而没有歧义。而你使用的KEIL使用ARMCC编译器肯定也能保证将你的C编译成汇编指令。所有的一环套一环都是实力的保证,倘若你真的找到了哪怕一丁丁的BUG 恭喜你 发达了。

出0入0汤圆

发表于 2020-10-19 10:32:31 | 显示全部楼层
unifax001 发表于 2020-10-19 10:15
st 公司用arm公司cpu内核做芯片 ;1 ARM公司专业设计CPU  既然敢卖 至少是指令系统设计完善,所有指令执行 ...

还别说,最后一环 Keil 的编译器相对来说是比较容易出问题的,在他们的更新记录里就能看到
尤其是涉及到一些新特性的时候,还是可以怀疑下编译器的

回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 19:54

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表