让人迷惑的无效指令。只是为了清零标志位,结果多执行很多无效指令,很奇怪

(gdb) si                       
0x000004b4      182                             USART1->STATR &= ~(USART_FLAG_TC|USART_FLAG_TXE);
   0x000004a8:       83 57 07 80     lhu     a5,-2048(a4)
   0x000004ac:       42 05   slli    a0,a0,0x10
   0x000004ae:       41 81   srli    a0,a0,0x10
   0x000004b0:       c2 07   slli    a5,a5,0x10
   0x000004b2:       c1 83   srli    a5,a5,0x10
=> 0x000004b4:       93 f7 f7 f3     andi    a5,a5,-193
   0x000004b8:       c2 07   slli    a5,a5,0x10
   0x000004ba:       c1 83   srli    a5,a5,0x10
   0x000004bc:       23 10 f7 80     sh      a5,-2048(a4)
(gdb) source /tmp/print_ax,gdb
a0:00000066; a1:00000000; a2:20000100; a3:40013800;
a4:40014000; a5:00000392; a6:00000000; a7:00000000;
(gdb) x /8wx 0x40013800        
0x40013800:     0x00000392      0x00000000      0x000001a1      0x0000200c
0x40013810:     0x00000000      0x00000040      0x00000000      0x00000000
(gdb) si                       
0x000004b8      182                             USART1->STATR &= ~(USART_FLAG_TC|USART_FLAG_TXE);
   0x000004a8:       83 57 07 80     lhu     a5,-2048(a4)  //a0:0x66
   0x000004ac:       42 05   slli    a0,a0,0x10 //a0:0x660000 a5:0x0392
   0x000004ae:       41 81   srli    a0,a0,0x10 //a0:0x66
   0x000004b0:       c2 07   slli    a5,a5,0x10 //a5:0x03920000
   0x000004b2:       c1 83   srli    a5,a5,0x10 //a5:0x0392
   0x000004b4:       93 f7 f7 f3     andi    a5,a5,-193 //0x0312
=> 0x000004b8:       c2 07   slli    a5,a5,0x10  //0x03120000
   0x000004ba:       c1 83   srli    a5,a5,0x10  //0x0312
   0x000004bc:       23 10 f7 80     sh      a5,-2048(a4)
(gdb) source /tmp/print_ax,gdb
a0:00000066; a1:00000000; a2:20000100; a3:40013800;
a4:40014000; a5:00000312; a6:00000000; a7:00000000;

不知道为何要加以上这么几条无效的指令,增加程序还多运行时间。+182>+180>+178>+174>+172>+170>+168>+166>+162>+182>+180>+178>+174>+172>+170>+168>+166>+162>

slli    a0,a0,0x10
slli    a0,a0,0x10
slli    a5,a5,0x10
slli    a5,a5,0x10

slli    a5,a5,0x10
slli    a5,a5,0x10

应该是编译器的问题。我记得之前有讨论过,但是我不知道怎么查看我的回复,论坛似乎只能查询我发表的主题?


182                             USART1->STATR &= ~(USART_FLAG_TC|USART_FLAG_TXE);
  0x00000408 <+164>:   lhu     a5,-2048(a4)
  0x0000040c <+168>:   slli    a5,a5,0x10
  0x0000040e <+170>:   srli    a5,a5,0x10
  0x00000410 <+172>:   andi    a5,a5,-193
  0x00000414 <+176>:   slli    a5,a5,0x10
  0x00000416 <+178>:   srli    a5,a5,0x10
  0x00000418 <+180>:   sh      a5,-2048(a4)

183                             USART1->DATAR = c;
=> 0x0000041c <+184>:   sh      a0,4(a3)

使用riscv-none-elf-gcc v12 版本得到的代码是少了两条slli    a0,a0,0x10,

两种编译器生成的程序都能正常运行。这么看来是编译器的问题。

我使用的优化级别是-0S,生成这样的指令不应该啊!


@梦珂0123有改进的方案吗?


终于整明白了,是半字存取指令与工作寄存器间为确保非需要位为零而做的操作。

但是字节存取指令却不需要这样。第一次遇上这样的需求。


只有登录才能回复,可以选择微信账号登录