首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

[求助]如何令CW编译时对位判断与位设置使用HC08汇编位判断与位设置指令?

[求助]如何令CW编译时对位判断与位设置使用HC08汇编位判断与位设置指令?

    按照PTA的方式定义了BITR,程序进行位判断与位设置,CodeWarrior在对BITR编译时使用ANSI C 的字节操作指令,需7条汇编指令占14个字节,不仅指令字节多且操作时间长。
    可是CW对PTA却使用HC08位判断与位设置指令,只需2条汇编指令和只占5个字节。
    如何令CW对位判断与位设置编译时使用位判断与位设置指令?
// 以下是C程序:
#include /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
#include "main_asm.h" /* interface to the assembly module */
/* 设置位操作寄存器*/
typedef union {
byte Byte;
struct {
byte BITR0 :1;
byte BITR1 :1;
byte BITR2 :1;
byte BITR3 :1;
byte BITR4 :1;
byte BITR5 :1;
byte BITR6 :1;
byte BITR7 :1;
} Bits;
} BITRSTR;
extern volatile BITRSTR _BITR 0x00000100;
#define BITR _BITR.Byte
#define BITR_BITR0 _BITR.Bits.BITR0
#define BITR_BITR1 _BITR.Bits.BITR1
#define BITR_BITR2 _BITR.Bits.BITR2
#define BITR_BITR3 _BITR.Bits.BITR3
#define BITR_BITR4 _BITR.Bits.BITR4
#define BITR_BITR5 _BITR.Bits.BITR5
#define BITR_BITR6 _BITR.Bits.BITR6
#define BITR_BITR7 _BITR.Bits.BITR7
#define BITR_BITR0_MASK 1
#define BITR_BITR1_MASK 2
#define BITR_BITR2_MASK 4
#define BITR_BITR3_MASK 8
#define BITR_BITR4_MASK 16
#define BITR_BITR5_MASK 32
#define BITR_BITR6_MASK 64
#define BITR_BITR7_MASK 128
volatile BITRSTR _BITR;

void main(void)
{
if (PTA_PTA0==0)   PTA_PTA1=0;
if (BITR_BITR0==0) BITR_BITR1=0;
}

// CW编译后形成的汇编指令列表文件:
  45: void main(void)
  46: {
  47:    if (PTA_PTA0==0) PTA_PTA1=0;
0000 000002 [5] BRSET 0,_PTA,L5 ;abs = 0005
0003 1300   [4] BCLR 1,_PTA
0005        [5] L5:
  48:
  49:    if (BITR_BITR0==0) BITR_BITR1=0;
0005 c60000 [4] LDA _BITR
0008 a501   [2] BIT #1
000a 2607   [3] BNE L13 ;abs = 0013
000c 450000 [3] LDHX _BITR
000f f6     [2] LDA ,X
0010 a4fd   [2] AND #-3
0012 f7     [2] STA ,X
0013        [5] L13:
  50: }
0013 81     [4] RTS
  51:

[此贴子已经被作者于2006-5-8 1:14:35编辑过]

[此贴子已经被作者于2006-5-8 1:18:26编辑过]

BITR要位于零页地址(0x0000-0x00FF)对位的操作才和PTA相同
 

[此贴子已经被作者于2006-5-8 18:03:21编辑过]

      高手啊,十分感谢!
      另外,不知是否清楚CW对于结构联合体的位定义每条语句的具体含义,比如byte Byte; ×××STR;等,查找很多资料均无说明,目前只知必须这样做,而不知为什么要这样做。
     再次感谢!

[此贴子已经被作者于2006-5-8 18:10:55编辑过]

typedef union {
byte Byte;
struct {
byte BITR0 :1;
byte BITR1 :1;
byte BITR2 :1;
byte BITR3 :1;
byte BITR4 :1;
byte BITR5 :1;
byte BITR6 :1;
byte BITR7 :1;
} Bits;
} BITRSTR;
extern volatile BITRSTR _BITR 0x00000100;

使用typedef定义一个名字为BITRSTR的联合体,使用联合体的好处是可以根据使用情况,自动开辟对应的空间。
比如对整个字节操作就使用联合体内的成员Byte,因为Byte是byte类型(即一个字节的大小);
对位操作,就使用联合体内结构体成员Bits的某一个成员,例如BITR0。 BITR0定义成byte类型,但其后面还跟有成员说明符:1,这个说明符指示了该变量只占用字节中一个bit的空间,根据在结构体中的位置,它占用的是bit0的空间。
这就返回到前面所说的联合体定义的好处,这时候编译器就知道对该变量的操作是位操作。
看了seuafu2005 的指点,回头再看汇编资料明明白白地说明在零页中可以使用位测试转移与位操作指令,看来使用C的人对汇编也必须深入了解,同时感谢本BBS对大家的帮助。

还有一点需请教:
如何用预处理伪指令将BITR定义到零页,而不是使用强制定位符号@到零页,
用#pragma DATA_SEG MY_ZEROPAGE语句似无效,(对普通的数据寄存器是有效的)
#pragma DATA_SEG MY_ZEROPAGE

typedef union {
byte Byte;
struct {
byte BITR0 :1;
byte BITR1 :1;
byte BITR2 :1;
byte BITR3 :1;
byte BITR4 :1;
byte BITR5 :1;
byte BITR6 :1;
byte BITR7 :1;
} Bits;
} BITRSTR;

BITRSTR _BITR;

#define BITR _BITR.Byte


我用pragma的方式定义是可以把_BITR放到零页的

除了定义之外,必须在程序中使用到BITR,否则编译器会做优化,不给BITR地址空间
    是的,是我搞错了,预处理指令#pragma DATA_SEG MY_ZEROPAGE可以把BITR设置在零页,但是C编译器对BITR仍旧使用ANSI C 的字节操作指令。
    好像必须使用强制定位符号@到零页后才能使用汇编位判断转移与位设置指令。
    另外,将寄存器使用强制定位符号@到零页须注意修改Project.prm文件中Z_RAM的范围。好像CW从Z_RAM命令的开始地址分配地址给寄存器,并不检查该地址是否已经被强制定位@占用,比如Project.prm文件中命令:
    Z_RAM = READ_WRITE 0x0060 TO 0x00FF;
    程序中定义 char a @0x60;
               char b;
    编译后发现a与b均分配在0x60地址。
    解决办法Z_RAM = READ_WRITE 0x0061 TO 0x00FF;

[此贴子已经被作者于2006-5-10 22:32:41编辑过]

感谢cnzbm的经验
返回列表