搜索
bottom↓
回复: 11

用AVR Studio + AVRGCC写死循环延时注意了,要加asm("nop");

[复制链接]

出0入0汤圆

发表于 2013-1-17 23:11:06 | 显示全部楼层 |阅读模式
如题~~~
以下是示例代码:
void usDelay(unsigned int dat)
{
        while(dat>0){
                dat--;
                asm("nop");//--如果这里不加上此指令,在调用时,反汇编查看,根本就没有调用usDelay(unsigned int dat);此函数
        }
}

不知道大家有没有这种情况?

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2013-1-17 23:32:25 | 显示全部楼层
您觉得您写的这个比avr-gcc的库里面那个好用?

出0入0汤圆

 楼主| 发表于 2013-1-18 00:16:03 | 显示全部楼层
aozima 发表于 2013-1-17 23:32
您觉得您写的这个比avr-gcc的库里面那个好用?

只是遇到有这种现象提醒一下而已,是编译器的关系

出0入0汤圆

发表于 2013-1-18 00:16:38 | 显示全部楼层
与优化有关,有时就把延时程序嵌入,所以没有CALL的。但仔细瞧,有延时在里面。

出0入0汤圆

 楼主| 发表于 2013-1-18 00:40:07 | 显示全部楼层
#include <avr/io.h>
#include "iolgt8f0xa.h"

#define        nIRQ        PA0                //JRF模块 中断信号,平时为高电平
#define        SDN        PA1                //JRF模块 芯片关断模式输入(高电平有效)
#define        nSEL        PA2                //JRF模块 SPI 片选输入(低电平有效)
#define        SCK           PA3                //JRF模块 SPI 串口时钟输入
#define        SDI        PA4                //JRF模块 SPI 串口数据输入
#define        SDO        PA5                //JRF模块 SPI 串口数据输出
#define        Test        PA7                //



void usDelay(unsigned int dat)
{
        while(dat>0){
                dat--;
                //asm("nop");//--这里取消与不取消,查看反汇编代码对比一下
        }
}

void write_spi(unsigned char dat)
{   //write data into the SPI register
  
    unsigned int i;
    PORTA &=~_BV(SCK);//SCLK==0;

    for (i=0;i<8;i++)
    {
                if ((dat & 0x80)==0x80)  //判断发送0或发送1
                {
                        PORTA |=_BV(SDI);//SDI==1;
                }               
                else
                {
                        PORTA &=~_BV(SDI);//SDI==0;
                }                 

                usDelay(10);
                PORTA |=_BV(SCK);//SCLK==1;

                dat <<= 1;
                usDelay(10);
                PORTA &=~_BV(SCK);//SCLK==0;

                usDelay(10);
    }
}
void MCU_Init(void)
{
        DDRA=0xde;
        PORTA=0x21;
}       
int main(void)
{
    MCU_Init();
    write_spi(0x55);
    while(1)
    {
        ;
    }
}
以上代码编译后的反汇编代码如下(已经没有了延时函数的存在):
--- LGT_Test3.c ----------------------------------------------------------------------------------
24:       }
+0000004A:   9508        RET                      Subroutine return
@0000004B: write_spi
27:       {   //write data into the SPI register
+0000004B:   9813        CBI       0x02,3         Clear bit in I/O register
+0000004C:   E020        LDI       R18,0x00       Load immediate
+0000004D:   E030        LDI       R19,0x00       Load immediate
34:                       if ((dat & 0x80)==0x80)  //判断发送0或发送1
+0000004E:   FF87        SBRS      R24,7          Skip if bit in register set
+0000004F:   C002        RJMP      PC+0x0003      Relative jump
36:                               PORTA |=_BV(SDI);//SDI==1;
+00000050:   9A14        SBI       0x02,4         Set bit in I/O register
+00000051:   C001        RJMP      PC+0x0002      Relative jump
40:                               PORTA &=~_BV(SDI);//SDI==0;
+00000052:   9814        CBI       0x02,4         Clear bit in I/O register
44:                       PORTA |=_BV(SCK);//SCLK==1;
+00000053:   9A13        SBI       0x02,3         Set bit in I/O register
48:                       PORTA &=~_BV(SCK);//SCLK==0;
+00000054:   9813        CBI       0x02,3         Clear bit in I/O register
32:           for (i=0;i<8;i++)
+00000055:   5F2F        SUBI      R18,0xFF       Subtract immediate
+00000056:   4F3F        SBCI      R19,0xFF       Subtract immediate with carry
+00000057:   3028        CPI       R18,0x08       Compare with immediate
+00000058:   0531        CPC       R19,R1         Compare with carry
+00000059:   F011        BREQ      PC+0x03        Branch if equal
46:                       dat <<= 1;
+0000005A:   0F88        LSL       R24            Logical Shift Left
+0000005B:   CFF2        RJMP      PC-0x000D      Relative jump
+0000005C:   9508        RET                      Subroutine return
55:               DDRA=0xde;
+0000005D:   ED8E        LDI       R24,0xDE       Load immediate
+0000005E:   B981        OUT       0x01,R24       Out to I/O location
56:               PORTA=0x21;
+0000005F:   E281        LDI       R24,0x21       Load immediate
+00000060:   B982        OUT       0x02,R24       Out to I/O location
57:       }       
+00000061:   9508        RET                      Subroutine return
@00000062: main
59:       {
+00000062:   ED8E        LDI       R24,0xDE       Load immediate
+00000063:   B981        OUT       0x01,R24       Out to I/O location
56:               PORTA=0x21;
+00000064:   E281        LDI       R24,0x21       Load immediate
+00000065:   B982        OUT       0x02,R24       Out to I/O location
61:           write_spi(0x55);
+00000066:   E585        LDI       R24,0x55       Load immediate
+00000067:   940E004B    CALL      0x0000004B     Call subroutine
+00000069:   CFFF        RJMP      PC-0x0000      Relative jump
61:           write_spi(0x55);
+0000006A:   94F8        CLI                      Global Interrupt Disable
+0000006B:   CFFF        RJMP      PC-0x0000      Relative jump

出0入0汤圆

发表于 2013-1-18 00:53:04 | 显示全部楼层
加volatile修饰

出0入0汤圆

发表于 2013-1-18 00:54:04 | 显示全部楼层
我这也一样 释放版本里没有 调试版本里有

出0入0汤圆

 楼主| 发表于 2013-1-18 01:13:51 | 显示全部楼层
ming180 发表于 2013-1-18 00:53
加volatile修饰


void  usDelay(volatile unsigned int usTime)//
{
        while(usTime>0){
                usTime--;
                //asm("nop");//--上面加上volatile修饰后,这里就可以取消了
        }
}

出0入442汤圆

发表于 2013-1-18 08:48:05 | 显示全部楼层
goodcode 发表于 2013-1-18 00:54
我这也一样 释放版本里没有 调试版本里有

ca,Keil写51时如果用高级C编译器,那么Release版本有很大几率不能正常工作。莫非这些嵌入式C编译器的优化有问题?

出0入0汤圆

发表于 2013-1-18 12:32:30 | 显示全部楼层
我觉得是bug WinAVR-20100110

出0入296汤圆

发表于 2013-1-23 00:37:27 | 显示全部楼层
本帖最后由 Gorgon_Meducer 于 2013-1-23 00:38 编辑

的确是bug,确认。仿真器在C单步模式下会有这个问题,进入汇编界面但不则不会出现。

出0入0汤圆

 楼主| 发表于 2013-1-23 02:29:00 | 显示全部楼层
Gorgon_Meducer 发表于 2013-1-23 00:37
的确是bug,确认。仿真器在C单步模式下会有这个问题,进入汇编界面但不则不会出现。 ...

哈哈~~~偶像也来发话了."BUG"
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-12 14:40

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表