奇怪的“保护变量”初始化代码 - 可以删除吗?

时间:2017-08-09 18:12:59

标签: c++ avr-gcc

我编写了一个示例程序来测试我的AVR库。这是命令行:

avr-gcc -g -Wall -mcall-prologues -fshort-enums -Os -ffreestanding -I./include -I./ -DF_CPU=8000000L -Wl,-gc-sections -Wl,-relax -mmcu=attiny1634 *.cpp -o main

检查生成的汇编代码我发现以下内容:

000001c6 <_GLOBAL__sub_I___vector_16>:
template<class driver> cqueue uart<driver>::rxq __attribute__ ((section (".noinit")));
 1c6:   20 91 09 01     lds     r18, 0x0109     ; 0x800109 <guard variable for uart<drv::uart0>::rxq>
 1ca:   30 91 0a 01     lds     r19, 0x010A     ; 0x80010a <guard variable for uart<drv::uart0>::rxq+0x1>
 1ce:   40 91 0b 01     lds     r20, 0x010B     ; 0x80010b <guard variable for uart<drv::uart0>::rxq+0x2>
 1d2:   50 91 0c 01     lds     r21, 0x010C     ; 0x80010c <guard variable for uart<drv::uart0>::rxq+0x3>
 1d6:   60 91 0d 01     lds     r22, 0x010D     ; 0x80010d <guard variable for uart<drv::uart0>::rxq+0x4>
 1da:   70 91 0e 01     lds     r23, 0x010E     ; 0x80010e <guard variable for uart<drv::uart0>::rxq+0x5>
 1de:   80 91 0f 01     lds     r24, 0x010F     ; 0x80010f <guard variable for uart<drv::uart0>::rxq+0x6>
 1e2:   90 91 10 01     lds     r25, 0x0110     ; 0x800110 <guard variable for uart<drv::uart0>::rxq+0x7>
 1e6:   a1 e0           ldi     r26, 0x01       ; 1
 1e8:   32 d0           rcall   .+100           ; 0x24e <__adddi3_s8>
 1ea:   20 93 09 01     sts     0x0109, r18     ; 0x800109 <guard variable for uart<drv::uart0>::rxq>
 1ee:   30 93 0a 01     sts     0x010A, r19     ; 0x80010a <guard variable for uart<drv::uart0>::rxq+0x1>
 1f2:   40 93 0b 01     sts     0x010B, r20     ; 0x80010b <guard variable for uart<drv::uart0>::rxq+0x2>
 1f6:   50 93 0c 01     sts     0x010C, r21     ; 0x80010c <guard variable for uart<drv::uart0>::rxq+0x3>
 1fa:   60 93 0d 01     sts     0x010D, r22     ; 0x80010d <guard variable for uart<drv::uart0>::rxq+0x4>
 1fe:   70 93 0e 01     sts     0x010E, r23     ; 0x80010e <guard variable for uart<drv::uart0>::rxq+0x5>
 202:   80 93 0f 01     sts     0x010F, r24     ; 0x80010f <guard variable for uart<drv::uart0>::rxq+0x6>
 206:   90 93 10 01     sts     0x0110, r25     ; 0x800110 <guard variable for uart<drv::uart0>::rxq+0x7>
 20a:   20 91 01 01     lds     r18, 0x0101     ; 0x800101 <guard variable for uart<drv::uart1>::rxq>
 20e:   30 91 02 01     lds     r19, 0x0102     ; 0x800102 <guard variable for uart<drv::uart1>::rxq+0x1>
 212:   40 91 03 01     lds     r20, 0x0103     ; 0x800103 <guard variable for uart<drv::uart1>::rxq+0x2>
 216:   50 91 04 01     lds     r21, 0x0104     ; 0x800104 <guard variable for uart<drv::uart1>::rxq+0x3>
 21a:   60 91 05 01     lds     r22, 0x0105     ; 0x800105 <guard variable for uart<drv::uart1>::rxq+0x4>
 21e:   70 91 06 01     lds     r23, 0x0106     ; 0x800106 <guard variable for uart<drv::uart1>::rxq+0x5>
 222:   80 91 07 01     lds     r24, 0x0107     ; 0x800107 <guard variable for uart<drv::uart1>::rxq+0x6>
 226:   90 91 08 01     lds     r25, 0x0108     ; 0x800108 <guard variable for uart<drv::uart1>::rxq+0x7>
 22a:   11 d0           rcall   .+34            ; 0x24e <__adddi3_s8>
 22c:   20 93 01 01     sts     0x0101, r18     ; 0x800101 <guard variable for uart<drv::uart1>::rxq>
 230:   30 93 02 01     sts     0x0102, r19     ; 0x800102 <guard variable for uart<drv::uart1>::rxq+0x1>
 234:   40 93 03 01     sts     0x0103, r20     ; 0x800103 <guard variable for uart<drv::uart1>::rxq+0x2>
 238:   50 93 04 01     sts     0x0104, r21     ; 0x800104 <guard variable for uart<drv::uart1>::rxq+0x3>
 23c:   60 93 05 01     sts     0x0105, r22     ; 0x800105 <guard variable for uart<drv::uart1>::rxq+0x4>
 240:   70 93 06 01     sts     0x0106, r23     ; 0x800106 <guard variable for uart<drv::uart1>::rxq+0x5>
 244:   80 93 07 01     sts     0x0107, r24     ; 0x800107 <guard variable for uart<drv::uart1>::rxq+0x6>
 248:   90 93 08 01     sts     0x0108, r25     ; 0x800108 <guard variable for uart<drv::uart1>::rxq+0x7>
 24c:   08 95           ret

0000024e <__adddi3_s8>:
 24e:   00 24           eor     r0, r0
 250:   a7 fd           sbrc    r26, 7
 252:   00 94           com     r0
 254:   2a 0f           add     r18, r26
 256:   30 1d           adc     r19, r0
 258:   40 1d           adc     r20, r0
 25a:   50 1d           adc     r21, r0
 25c:   60 1d           adc     r22, r0
 25e:   70 1d           adc     r23, r0
 260:   80 1d           adc     r24, r0
 262:   90 1d           adc     r25, r0
 264:   08 95           ret

00000266 <__tablejump2__>:
 266:   ee 0f           add     r30, r30
 268:   ff 1f           adc     r31, r31
 26a:   05 90           lpm     r0, Z+
 26c:   f4 91           lpm     r31, Z
 26e:   e0 2d           mov     r30, r0
 270:   09 94           ijmp

变量uart<drv::uart0>::rxq>定义如下(uart<drv::uart0>::rxq>具有相似的定义):

namespace drv {

struct uart0
{
    static void putchar(char c) { UDR0 = c; }
};

}   /* namespace drv */



class uart0 : uart<drv::uart0>
{
    ...
};

template <class driver>
class uart : public driver
{
protected:
    static cqueue rxq;

public:
    static char getchar() { ... }
};

template<class driver> 
cqueue uart<driver>::rxq __attribute__ ((section (".noinit")));

在上面,cqueue是循环缓冲类:

class cqueue
{
protected:
    typedef union {
        struct {
            uint8_t head: 4;
            uint8_t tail: 4;
        };
        uint8_t nibbles;
    } nibbles_t;

    // Indices and data initialized with zeroes
    volatile nibbles_t ptr;
    qchar data[ 1 << 4 ];

public:
    bool is_empty() const { return ptr.head == ptr.tail; }
    void reset() { ptr.head = ptr.tail = 0; }
    uint8_t available() const { ... }
    bool put(qchar) { ... }
    qchar get() { ... }
};

循环缓冲区意味着未初始化,因此我不明白为什么以及守卫代码在那里做什么。尽管添加.noinit部分代码仍然存在并且正在咀嚼闪存的一部分(几乎 200字节,只是为了控制 32 !)我'而宁愿保持。

从程序开头调用保护代码:

00000124 <__do_global_ctors>:
 124:   10 e0           ldi     r17, 0x00       ; 0
 126:   c4 e8           ldi     r28, 0x84       ; 132
 128:   d0 e0           ldi     r29, 0x00       ; 0
 12a:   03 c0           rjmp    .+6             ; 0x132 <__do_global_ctors+0xe>
 12c:   21 97           sbiw    r28, 0x01       ; 1
 12e:   fe 01           movw    r30, r28
 130:   9a d0           rcall   .+308           ; 0x266 <__tablejump2__>
 132:   c3 38           cpi     r28, 0x83       ; 131
 134:   d1 07           cpc     r29, r17
 136:   d1 f7           brne    .-12            ; 0x12c <__do_global_ctors+0x8>

如何告诉编译器不要添加该保护代码?

0 个答案:

没有答案