在PIC16汇编中使用宏创建高级IF ELSE ENDIF

时间:2011-03-29 13:29:11

标签: assembly macros pic mplab

我尝试在PIC16F84的汇编中模拟IF().... ELIF .... ENDIF,但它似乎不适用于多个用法。我试图在两个地方使用这样的东西,但它给出了一些标签重复的错误。不应该在标签中替换宏中的参数吗? (名称在true_name中:)

_f macro name
  btfsc EQUAL,0
  goto true_name
  goto false_name
  true_name:
endm

_lse macro name
  goto next_name
  false_name:
endm

_ndif macro name
  goto next_name
  next_name:
endm

;; usage example
_f label1
  ...
_lse label1
  ...
_ndif 

3 个答案:

答案 0 :(得分:1)

我认为一个人可以做得更好。这里有一些if-else-endif宏可以嵌套五个深度。不幸的是,由于汇编程序不接受“#ifndef if #v(lvl)”所以我无法将if1,if2 ...的定义设置得很好,因此它们的嵌套值将嵌套级别限制为5深。这些符号计算给定嵌套级别的Ifs数,因此可以附加唯一标签。包含了一个无意义的例子。

xIf macro L,R,A

#ifndef lvl
lvl=0
#endif
lvl=lvl+1

#ifndef if1
if1=0
if2=0
if3=0
if4=0
if5=0
#endif

if#v(lvl)=if#v(lvl)+1

    movf    R,A
    xorlw L
    bnz   _false_#v(lvl)_#v(if#v(lvl))
    endm 

xElse macro
    bra  _end_#v(lvl)_#v(if#v(lvl))
_false_#v(lvl)_#v(if#v(lvl)):
    endm

xEndIf macro
_end_#v(lvl)_#v(if#v(lvl)):
lvl=lvl-1
    endm

    xIf 123,STATUS,A
        clrf    TMR3H,A
        xIf 75,STATUS,A
            clrf    TMR3H,A
        xElse
            setf    TMR3L,A
        xEndIf
    xElse
        setf    TMR3H,A
    xEndIf

答案 1 :(得分:0)

不要使用从一个宏到另一个宏的跳转,这很危险

无需使用唯一标签。 在MPLAB下有两种方法可以做到这一点:

1)具有LOCAL指令的案例

_f macro name
 LOCAL true_name
      btfsc   EQUAL,0
      goto    true_name
      goto    name  
true_name:
endm

2)使用$作为当前内存地址指针的情况。

_f macro name
      btfsc   EQUAL,0
      goto    $+1
      goto    name
endm

答案 2 :(得分:0)

我有点用MPLAB变量解决了这个问题,这是测试寄存器和文字之间相等性的一个例子:

_f_equal_literal macro register,literal,name
    movlw literal
    subwf register,0
    btfss STATUS,2 ;bit indicating result is zero
    goto _false#v(name)
    endm

_lse macro name
    goto _next#v(name)
_false#v(name):
    endm

_ndif macro name
_next#v(name):
    endm

请注意,我没有使用goto _true#v(name)_true#v(name):标签,您只需要确定是否需要btfssbtfsc

您可以拥有一个_lse_ndif宏,并且有_f个语句的多个宏。

GJ的解决方案没有next标签,因此真正的分支将执行false分支。


您需要为每个if-else-endif构造定义一个变量。 如果变量名称描述if-else-endif用于什么,它甚至可能有用。

示例:

变量testing_something = 123

_f_equal_literal some_register,some_value,testing_something
                ...       

_lse testing_something
                ...        

_ndif testing_something