【解析新特性】300W单路输出工业电源>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » GCC 熟悉GCC的朋友请进。

共2条 1/1 1 跳转至

GCC 熟悉GCC的朋友请进。

院士
2006-12-22 22:43:00    评分
GCC 熟悉GCC的朋友请进。



关键词: 熟悉     朋友     请进    

院士
2006-12-22 22:43:00    评分
2楼
问 两条功能基本一样的语句为什么编译后的结果会不同?
前边的一条编译后是一条位测试指令,
而后一条编译后是一条IO输入指令,
不知为何,郁闷。
下面的那条指令让我找了两天原因了,
可是找不到原因,请高手指点。

128:atmega16.c    ****       if(bit_is_set(ADCSRA,ADSC))
477                   .LM68:
478 017c 3699              sbic 38-0x20,6
129:atmega16.c    ****
130:atmega16.c    ****       
131:atmega16.c    ****
132:atmega16.c    ****        if(bit_is_set(UCSRA,UDRE))
480                   .LM69:
481 017e 8BB1              in r24,43-0x20 1: 测试过了,没有任何问题。不过当你的if后没有任何语句时,就是一个in指令。否则就是sbic指令。

     if(bit_is_set(ADCSRA,ADSC))    aa = 7;
178:    36 9b           sbis    0x06, 6    ; 6
17a:    02 c0           rjmp    .+4          ; 0x180
17c:    87 e0           ldi    r24, 0x07    ; 7
17e:    01 c0           rjmp    .+2          ; 0x182
    else    aa=8;
180:    88 e0           ldi    r24, 0x08    ; 8
182:    80 93 78 00     sts    0x0078, r24
    
    if(bit_is_set(UCSRA,UDRE))    aa = 12;
186:    5d 9b           sbis    0x0b, 5    ; 11
188:    02 c0           rjmp    .+4          ; 0x18e
18a:    8c e0           ldi    r24, 0x0C    ; 12
18c:    01 c0           rjmp    .+2          ; 0x190
    else    aa=13;
18e:    8d e0           ldi    r24, 0x0D    ; 13
…………………………



     
     if(bit_is_set(ADCSRA,ADSC))    aa = 7;
178:    36 9b           sbis    0x06, 6    ; 6
17a:    02 c0           rjmp    .+4          ; 0x180
17c:    87 e0           ldi    r24, 0x07    ; 7
17e:    01 c0           rjmp    .+2          ; 0x182
    else    aa=8;
180:    88 e0           ldi    r24, 0x08    ; 8
182:    80 93 78 00     sts    0x0078, r24
    
    if(bit_is_set(UCSRA,UDRE));
186:    8b b1           in    r24, 0x0b    ; 11
………………

190:    80 93 78 00     sts    0x0078, r24 2: 这是为什么?我刚才按照楼上仁兄所说,试了一下,的确是这样。
我的前一个IF后面是有语句的,而后一个IF的后面是一个空语句。
所以有上面的结果,这是为什么呢?  3: 当然有道理了。如果有if指令那么sbic是对了。否则用一个in指令好。因为一个in指令为一个指令周期,而sbic如果跳转则就是两个指令周期了。可见gcc是多么的聪明! 4: 要理解定义#define bit_is_set(sfr, bit) (sfr & _BV(bit))
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + 0x20)
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))

如果if表达式后有语句,根据C语法定义,必然会生成跳转指令。
但如果if表达式后是空语句,按C语法来说这条if表达式是没有任何意义的,除非 (1) if表达式中含有赋值语句;(2) 表达式中有对volatile变量访问的语句。

而在楼主和版主发现的问题,正是上面所说的第(2)种情况,在这种情况下,编译器必须生成对UCSRA的访问指令,但又无法生成跳转指令(也确实不需要跳转),所以只有生成in指令而不能用sbic,sbis了。 5: 谢谢楼上各位老兄指点,在此表示感谢其实我感觉GCC还是挺好用的,生成的代码很简练

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]