IAR编译器生成Cortex M3汇编代码的相关问题

  IAR如何查看C源代码生成的汇编指令:options->C/C++ Compiler ->List->Output list file & Output assembler file,生成的文件在工程目录List文件夹下。

  IAR生成的汇编文件中前几行就说明了 Cpu mode = thumb,但是Cortex M3的指令集是thumb-2指令集,thumb指令集是16位指令集,而thumb-2是16、32位混合指令集。那么就有一个疑问,IAR生成的汇编代码到底是thumb还是thumb-2的,如果是thumb的,那么Cortex M3引入的高效的thumb-2指令岂不是白费了。上述的思考是建立在对知识没有彻底了解之前,或许有漏洞,主要还是引出下面的实验结果。

  实验主要为解疑:

  0xF081 0x0168      EOR      R1,R1,#0x68 这句到底是一个32位指令,还是两个16位指令,前两个16进制数是机器码,要是合着一起用32位写也就没歧义了。

  测试用的源代码:

uint16_t test_asm(void){

  uint32_t i=0;
  volatile static uint8_t u8=0;
  volatile static uint32_t u32=0;
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
  for(i=0;i<10000000;i++)
  {
    u8++;
    u8++;
  }
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
  for(i=0;i<10000000;i++)
  {
    u32 ^=0x68;
    u32 ^=0x68;
    u32 ^=0x68;
  } 
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);  
  return 0;
}
  下面是生成的汇编代码:

     26            HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
   \   00000004   0x2201             MOVS     R2,#+1
   \   00000006   0x2101             MOVS     R1,#+1
   \   00000008   0x4814             LDR.N    R0,??test_asm_0  ;; 0x40010c00
   \   0000000A   0x.... 0x....      BL       HAL_GPIO_WritePin
     27            for(i=0;i<10000000;i++)
   \   0000000E   0x4814             LDR.N    R0,??test_asm_0+0x4  ;; 0x989680
   \   00000010   0x4A14             LDR.N    R2,??test_asm_0+0x8
     28            {
     29              u8++;
   \                     ??test_asm_1: (+1)
   \   00000012   0x7811             LDRB     R1,[R2, #+0]
   \   00000014   0x1C49             ADDS     R1,R1,#+1
   \   00000016   0x7011             STRB     R1,[R2, #+0]
     30              u8++;
   \   00000018   0x7811             LDRB     R1,[R2, #+0]
   \   0000001A   0x1C49             ADDS     R1,R1,#+1
   \   0000001C   0x7011             STRB     R1,[R2, #+0]
     31            }
   \   0000001E   0x1E40             SUBS     R0,R0,#+1
   \   00000020   0xD1F7             BNE.N    ??test_asm_1
     32            HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
   \   00000022   0x2200             MOVS     R2,#+0
   \   00000024   0x2101             MOVS     R1,#+1
   \   00000026   0x480D             LDR.N    R0,??test_asm_0  ;; 0x40010c00
   \   00000028   0x.... 0x....      BL       HAL_GPIO_WritePin
     33            for(i=0;i<10000000;i++)
   \   0000002C   0x480C             LDR.N    R0,??test_asm_0+0x4  ;; 0x989680
   \   0000002E   0x4A0E             LDR.N    R2,??test_asm_0+0xC
     34            {
     35              u32 ^=0x68;
   \                     ??test_asm_2: (+1)
   \   00000030   0x6811             LDR      R1,[R2, #+0]
   \   00000032   0xF081 0x0168      EOR      R1,R1,#0x68
   \   00000036   0x6011             STR      R1,[R2, #+0]
     36              u32 ^=0x68;
   \   00000038   0x6811             LDR      R1,[R2, #+0]
   \   0000003A   0xF081 0x0168      EOR      R1,R1,#0x68
   \   0000003E   0x6011             STR      R1,[R2, #+0]
     37              u32 ^=0x68;
   \   00000040   0x6811             LDR      R1,[R2, #+0]
   \   00000042   0xF081 0x0168      EOR      R1,R1,#0x68
   \   00000046   0x6011             STR      R1,[R2, #+0]
     38            } 
   \   00000048   0x1E40             SUBS     R0,R0,#+1
   \   0000004A   0xD1F1             BNE.N    ??test_asm_2
     39            HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);  
  从汇编可以看出来,加法只需一个16位指令,异或需要32位指令(两个16位)。其他的指令都是类似或者一样的。加法的循环需要循环执行的指令有8条,时间就是8T。如果异或需要两个周期那么其循环的指令时间是14T,如果异或需要一个周期,循环指令就是11T。

  下面是逻辑分析仪的截图


分别是2.71s和3.75s。那么可以确定虽然写了两个16位机器码,但是写在一行就是一个32位ARM指令。


  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值