共2条
1/1 1 跳转至页
问
两条功能基本一样的语句为什么编译后的结果会不同?
前边的一条编译后是一条位测试指令,
而后一条编译后是一条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还是挺好用的,生成的代码很简练
前边的一条编译后是一条位测试指令,
而后一条编译后是一条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 跳转至页
回复
| 有奖活动 | |
|---|---|
| 2026年“我要开发板活动”第三季,开始了! | |
| 硬核工程师专属补给计划——填盲盒 | |
| “我踩过的那些坑”主题活动——第002期 | |
| 【EEPW电子工程师创研计划】技术变现通道已开启~ | |
| 发原创文章 【每月瓜分千元赏金 凭实力攒钱买好礼~】 | |
| 【EEPW在线】E起听工程师的声音! | |
| 高校联络员开始招募啦!有惊喜!! | |
| 【工程师专属福利】每天30秒,积分轻松拿!EEPW宠粉打卡计划启动! | |
我要赚赏金打赏帖 |
|
|---|---|
| 【分享开发笔记,赚取电动螺丝刀】在音频测试中顺序的调整可改变功效被打赏¥18元 | |
| 【分享开发笔记,赚取电动螺丝刀】点阵显示模块及其应用-----献给新年的小礼物被打赏¥22元 | |
| 基于地奇星开发板的数码管模块显示技术被打赏¥23元 | |
| window下生成compilecommands.json的的方法被打赏¥22元 | |
| 【S32K3XX】GPIO中断配置被打赏¥26元 | |
| 【分享开发笔记,赚取电动螺丝刀】WS2812B的RGB灯介绍以及驱动方法被打赏¥25元 | |
| PTC与NTC功能常规对比被打赏¥14元 | |
| 【S32K3XX】核间通信MU使用被打赏¥27元 | |
| 【分享开发笔记,赚取电动螺丝刀】关于3pin锂电池接口的介绍/使用被打赏¥16元 | |
| 以启明云端ESP32P4开发板实现TF卡读写功能被打赏¥28元 | |
我要赚赏金
