avr-gcc困境:忽略永久变量/寄存器绑定。为什么?

时间:2017-08-13 15:40:23

标签: c avr-gcc

仍在努力与AVR组装。这一次avr-gcc似乎完全忽略了我对permanently bind a local variable to a register的指示。这是一个例子 - 这当然只是一个例子,而不是最终的代码:

// C code:
ISR(USART1_RX_vect)
{
    register uint8_t c asm("r3") = UDR1;
    tty1::buffer[tty1::ptr.head] = c;
}

// Generated assembly:
000000d8 <__vector_20>:
  d8:   1f 92           push    r1
  da:   0f 92           push    r0
  dc:   0f b6           in      r0, SREG        ; 63
  de:   0f 92           push    r0
  e0:   11 24           eor     r1, r1
  e2:   8f 93           push    r24
  e4:   ef 93           push    r30
  e6:   ff 93           push    r31
  e8:   80 91 73 00     lds     r24, UDR1       ; 0x800073 <__EEPROM_REGION_LENGTH__+0x7f0073>
  ec:   e0 91 01 01     lds     r30, 0x0101     ; 0x800101 <tty<drv::uart1>::ptr>
  f0:   e2 95           swap    r30
  f2:   ef 70           andi    r30, 0x0F       ; 15
  f4:   f0 e0           ldi     r31, 0x00       ; 0
  f6:   ee 5f           subi    r30, 0xFE       ; 254
  f8:   fe 4f           sbci    r31, 0xFE       ; 254
  fa:   80 83           st      Z, r24
  fc:   ff 91           pop     r31
  fe:   ef 91           pop     r30
 100:   8f 91           pop     r24
 102:   0f 90           pop     r0
 104:   0f be           out     SREG, r0        ; 63
 106:   0f 90           pop     r0
 108:   1f 90           pop     r1
 10a:   18 95           reti

- 请给我r3

- 当然可以!这是r24

我可以问r2r7之间的任何寄存器,编译器只需要它想要的任何东西!它与UDR1无关,它与我指定的c无关。如果它什么都不做,该指令有什么意义呢?我该如何控制编译器选择的寄存器?

问题«为什么我想将变量分配给寄存器?»我回复«因为生成的代码对于中断来说是次优的而我想要罚款控制生成的程序集。»到目前为止,这对我来说是一个麻烦。

仍在使用avr-gcc版本7.1.0 ...

1 个答案:

答案 0 :(得分:0)

从中断服务例程(ISR)中删除对全局范围的声明。 GCC允许全局和本地永久绑定。你的是ISR范围,在你的情况下是无用的。

我会尽力给出更详细的解释。

本地范围

  1. 从绑定停止注册为注册,并将其视为存储位置。
  2. 相同的优化规则适用于任何其他自动变量。
  3. ISR必须恢复所有寄存器(全局范围内的那些寄存器除外) - 因此不会产生任何副作用 - 即使寄存器绑定在本地范围内。
  4. 查看代码: 对https://godbolt.org/g/HsjvCahttps://godbolt.org/g/ZGjvRE进行了优化。

    本地绑定不会更改任何通用寄存器使用规则。

    如果绑定寄存器 - 您不能调用任何没有带有寄存器绑定(全局范围)的头文件编译的函数。在本地范围内,对任何函数的调用使本地绑定无效。