C语言局部变量,全局变量,const和宏定义的汇编分析。

使用的C代码如下:

GPIO_TypeDef *gGpio = GPIOA;
GPIO_TypeDef *const gcGpio = GPIOA;
int main(void)
{
    GPIO_TypeDef *gpio = GPIOA;
    gpio->BRR = 4;
    gGpio->BRR = 6;
    gcGpio->BRR = 5;
    GPIOA->BRR = 7;
    while(1);
}

编译后生成的主要汇编代码如下:

-----------------------------------1------------------------
   102:     GPIO_TypeDef *gpio = GPIOA; 
0x08000612 4807      LDR      r0,[pc,#28]  ; @0x08000630
   103:     gpio->BRR = 4; 
0x08000614 2104      MOVS     r1,#0x04
0x08000616 6141      STR      r1,[r0,#0x14]
-----------------------------------1------------------------
-----------------------------------2------------------------
   104:     gGpio->BRR = 6; 
0x08000618 2106      MOVS     r1,#0x06
0x0800061A 4A06      LDR      r2,[pc,#24]  ; @0x08000634
0x0800061C 6812      LDR      r2,[r2,#0x00]
0x0800061E 6151      STR      r1,[r2,#0x14]
-----------------------------------2------------------------
-----------------------------------3------------------------
   105:     gcGpio->BRR = 5; 
0x08000620 2105      MOVS     r1,#0x05
0x08000622 4A03      LDR      r2,[pc,#12]  ; @0x08000630
0x08000624 3214      ADDS     r2,r2,#0x14
0x08000626 6011      STR      r1,[r2,#0x00]
-----------------------------------3------------------------
-----------------------------------4------------------------
   106:     GPIOA->BRR = 7; 
0x08000628 2107      MOVS     r1,#0x07
0x0800062A 6011      STR      r1,[r2,#0x00]
-----------------------------------4------------------------
   107:     while(1); 
0x0800062C BF00      NOP      
0x0800062E E7FE      B        0x0800062E

对于局部变量gpio:从生成的汇编代码块1,可看出包括自身初始化共生成3句汇编代码。

对于全局变量gGpio:从生成的汇编代码块2,可看出不包括自身初始化共生成4句汇编代码。

对于全局const变量gcGpio:从生成的汇编代码块3,可看出不包括自身初始化代码共生成4句汇编代码。

对于宏定义GPIOA:从生成的汇编代码块4,可看出只生成2句汇编代码。

从以上结果,看上去宏定义最快,但实际可能并非如此。以下为分析:

生成的汇编代码块4中所使用的寄存器r2,初值来自汇编代码块3 。所以我们无法确定各自到底会生成多少代码,我们修改下C文件重新生成下汇编代码。

修改后的C源码:

GPIO_TypeDef *gGpio = GPIOA;
GPIO_TypeDef *const gcGpio = GPIOB;
int main(void)
{
    GPIO_TypeDef *gpio = GPIOC;
    gpio->BRR = 4;
    gGpio->BRR = 6;
    gcGpio->BRR = 5;
    GPIOD->BRR = 7;
    while(1);
}

我们分别使用不同的宏来初始化不同的变量。得到的汇编如下:

----------------------------------1-------------------------------------
   102:     GPIO_TypeDef *gpio = GPIOC; 
0x08000612 4807      LDR      r0,[pc,#28]  ; @0x08000630
   103:     gpio->BRR = 4; 
0x08000614 2104      MOVS     r1,#0x04
0x08000616 6141      STR      r1,[r0,#0x14]
----------------------------------1-------------------------------------
----------------------------------2-------------------------------------
   104:     gGpio->BRR = 6; 
0x08000618 2106      MOVS     r1,#0x06
0x0800061A 4A06      LDR      r2,[pc,#24]  ; @0x08000634
0x0800061C 6812      LDR      r2,[r2,#0x00]
0x0800061E 6151      STR      r1,[r2,#0x14]
----------------------------------2-------------------------------------
----------------------------------3-------------------------------------
   105:     gcGpio->BRR = 5; 
0x08000620 2105      MOVS     r1,#0x05
0x08000622 4A05      LDR      r2,[pc,#20]  ; @0x08000638
0x08000624 6011      STR      r1,[r2,#0x00]
----------------------------------3-------------------------------------
----------------------------------4-------------------------------------
   106:     GPIOD->BRR = 7; 
0x08000626 2107      MOVS     r1,#0x07
0x08000628 4A04      LDR      r2,[pc,#16]  ; @0x0800063C
0x0800062A 6011      STR      r1,[r2,#0x00]
----------------------------------4-------------------------------------

从当前数据可得出结论:define = gcGpio <= gpio < gGpio 。

即:宏定义和const变量较快,其次是局部变量,全局变量最慢。且全局变量使用两次LDR指令,第一次同其他三种一样都是从Load Area取得当前所需要的值(变量地址)。第二次则变为从RAM中获取值(变量值)。

另,经验证,再不开启优化的情况下。使用base + offset = *(base + offset)的格式,生成的汇编代码比较精简。若使用结构体的指针格式,生成的汇编代码可能会多次进行基址记载和索引操作,比较臃肿。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值