создать высокоуровневый IF ELSE ENDIF с макросами в сборке PIC16 - PullRequest
1 голос
/ 29 марта 2011

Я пытался смоделировать IF () .... ELIF .... ENDIF в сборке для PIC16F84, но, похоже, он не работает для более чем одного использования. Я пытался использовать что-то подобное в двух местах, но выдает ошибку, что метка дублируется. Не следует ли заменить параметр из макроса в метках? (имя в 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 ]

1 голос
/ 25 октября 2012

Я думаю, что можно сделать немного лучше. Вот некоторые макросы if-else-endif, которые могут быть вложены в пять глубин. К сожалению, я не смог сделать определения if1, if2 .. столь хорошими, как хотелось бы, так как ассемблер не принимает "#ifndef if # v (lvl)", поэтому макросы в том виде, в котором они стоят, ограничивают уровень вложенности пятью глубокий. Эти символы подсчитывают количество If на данном уровне вложенности, поэтому можно прикрепить уникальные метки. Бессмысленный пример включен.

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
0 голосов
/ 31 марта 2011

Я вроде решил эту проблему с переменными 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):, вам нужно будет просто определить, нужны ли вам btfss или btfsc.

Вы можете иметь один макрос _lse и _ndif и иметь несколько макросов для операторов _f.

Решение GJ не имеет метки next, поэтому истинная ветвь будет выполнять ложную ветвь.


Вам необходимо определить переменную для каждой конструкции if-else-endif. Это может быть даже полезно, если имя переменной описывает, для чего используется if-else-endif.

Пример: * * один тысяча двадцать-одна

переменная testing_something = 123

_f_equal_literal some_register,some_value,testing_something
                ...       

_lse testing_something
                ...        

_ndif testing_something
0 голосов
/ 29 марта 2011

Не используйте переходы от одного макроса к другому, это опасно .

Нет необходимости использовать уникальные метки. Два способа сделать этопод 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
...