c - STM32f105 BLT指令重定位局部变量

标签 c assembly arm embedded stm32

在 Windows 7 上使用 Keil uVison 4 我有一个 stm32f105 的 c 项目,它表现出非常奇怪的行为。我用调试器检查了它,经过几个小时的错误追踪,我将错误定位到来自其他项目中已经测试过的函数。看起来像这样:

uint8_t can_add_filter_mask(can_t* this, uint32_t id, uint32_t id_mask, can_frm_type_t type, can_frm_type_t type_mask)
{
  CAN_FilterInitTypeDef filt;

    /* Empty filter available? */
    if(this->filter_len >= 14)
    {
        return FALSE;
    }

    /* Select filter number */
    if(this->canx == CAN1)
        filt.CAN_FilterNumber = this->filter_len + 0;
    else
        filt.CAN_FilterNumber = this->filter_len + 14;
    this->filter_len++;

    ...
    //filt is read
    CAN_FilterInit(&filt);
}

这样结构 filt 在任何分配后都不会改变!然后我更改了反汇编,如下(抱歉有点长):

   108: uint8_t can_add_filter_mask(can_t* this, uint32_t id, uint32_t id_mask, can_frm_type_t type, can_frm_type_t type_mask) 
0x08001B22 BD70      POP      {r4-r6,pc}
   109: { 
   110:   CAN_FilterInitTypeDef filt; 
   111:  
   112:         /* Empty filter available? */ 
0x08001B24 E92D41FF  PUSH     {r0-r8,lr}
0x08001B28 4604      MOV      r4,r0
0x08001B2A 460D      MOV      r5,r1
0x08001B2C 4690      MOV      r8,r2
0x08001B2E 461E      MOV      r6,r3
0x08001B30 9F0A      LDR      r7,[sp,#0x28]
   113:         if(this->filter_len >= 14) 
   114:         { 
0x08001B32 7C20      LDRB     r0,[r4,#0x10]
0x08001B34 280E      CMP      r0,#0x0E
0x08001B36 DB03      BLT      0x08001B40
   115:                 return FALSE; 
0x08001B38 2000      MOVS     r0,#0x00
   151: } 
   152:  
   153: /******************************************************************************/ 
   154: void can_clr_filter(can_t* this) 
0x08001B3A B004      ADD      sp,sp,#0x10
0x08001B3C E8BD81F0  POP      {r4-r8,pc}
   119:         if(this->canx == CAN1) 
0x08001B40 4970      LDR      r1,[pc,#448]  ; @0x08001D04
0x08001B42 6820      LDR      r0,[r4,#0x00]
0x08001B44 4288      CMP      r0,r1
0x08001B46 D103      BNE      0x08001B50
   120:                 filt.CAN_FilterNumber = this->filter_len + 0; 
   121:         else 
0x08001B48 7C20      LDRB     r0,[r4,#0x10]
0x08001B4A F88D000A  STRB     r0,[sp,#0x0A]
0x08001B4E E004      B        0x08001B5A
   122:                 filt.CAN_FilterNumber = this->filter_len + 14; 
0x08001B50 7C20      LDRB     r0,[r4,#0x10]
0x08001B52 300E      ADDS     r0,r0,#0x0E
0x08001B54 B2C0      UXTB     r0,r0
0x08001B56 F88D000A  STRB     r0,[sp,#0x0A]
   123:         this->filter_len++; 
   124:  
   125:         /* Select mask mode */ 
0x08001B5A 7C20      LDRB     r0,[r4,#0x10]
0x08001B5C 1C40      ADDS     r0,r0,#1
0x08001B5E 7420      STRB     r0,[r4,#0x10]

我不是汇编专家,也不是 ARM 专家,但我已经在汇编上进行了一些编程,对我来说,它看起来不错。我注意到有点奇怪的是,中间是另一个函数 can_clr_filter 的一部分,所以看起来编译器正在重用一些代码,尽管所有优化都被关闭。有趣的是,当我检查 filt.CAN_FilterNumber 变量的地址时,它在该行之后发生了变化

0x08001B36 DB03      BLT      0x08001B40

从地址0x20002262到地址0x20002252。所以所有的改变都被应用到了内存中的其他地方!在我将变量声明为静态后,问题就消失了,尽管对我来说实际发生的事情是个谜...局部变量怎么会被指令 BLT 重定位到另一个地址?或者 uVision 调试器是否可以通过观察 &filt.CAN_FilterNumber 显示错误的引用值?

最佳答案

因为您没有发布此片段中的整个函数,所以我只能猜测:

  1. 仅对局部变量进行赋值,但它不会在程序中的任何地方使用,并且可能会从生成的代码中删除。
  2. 不要在编译器中寻找错误。它们非常好,但我还没有找到任何(我是一个非常活跃的编码员)。总是当有人说:“这是反汇编列表,编译器是错误的”时,错误是由提问者在某个地方犯的。当您调试程序时,请忘记反汇编。你只是浪费时间。

关于c - STM32f105 BLT指令重定位局部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43995164/

相关文章:

c - 使用信号和 sigpipe

c - 结构体和链表

c - 如何使用 Arm Assembly/C 确定 Raspberry Pi 板版本?

c++ - 有人知道这个 C++ 内联汇编的作用吗?

architecture - 具有多架构的计算机可能吗?

arm - Raspberry Pi 引导加载程序如何工作?

C 段错误 : 11 fgets

CRC ECMA-182 引用

assembly - MIPS 中的整数绝对值?

embedded - 使用USB引导加载程序时如何设置ARM用户应用程序起始地址?