Assembly 使用PIC16汇编中的宏创建高级IF-ELSE-ENDIF
我试着模拟一下如果。。。。埃利夫。。。。ENDIF在PIC16F84的汇编中,但它似乎不能用于多种用途。我试着在两个地方使用类似的东西,但它给出了一些错误,标签是重复的。宏中的参数不也应该在标签中替换吗?(真实姓名:)Assembly 使用PIC16汇编中的宏创建高级IF-ELSE-ENDIF,assembly,macros,pic,mplab,Assembly,Macros,Pic,Mplab,我试着模拟一下如果。。。。埃利夫。。。。ENDIF在PIC16F84的汇编中,但它似乎不能用于多种用途。我试着在两个地方使用类似的东西,但它给出了一些错误,标签是重复的。宏中的参数不也应该在标签中替换吗?(真实姓名:) 不要使用从一个宏到另一个宏的跳转,这很危险 不需要使用唯一的标签。 在MPLAB下,有两种方法可以做到这一点: 1) 本地指令案例 _f macro name LOCAL true_name btfsc EQUAL,0 goto true_na
不要使用从一个宏到另一个宏的跳转,这很危险 不需要使用唯一的标签。 在MPLAB下,有两种方法可以做到这一点: 1) 本地指令案例
_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
不要使用从一个宏到另一个宏的跳转,这很危险 不需要使用唯一的标签。 在MPLAB下,有两种方法可以做到这一点: 1) 本地指令案例
_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
我用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#v(name)
和u-true#v(name):
标签,您只需考虑是否需要btfss
或btfsc
您可以有一个\u lse
和\u ndif
宏,也可以有多个\u f
语句的宏
GJ的解决方案没有next
标签,因此true分支将执行false分支
您需要为每个if-else-endif构造定义一个变量。 如果变量名描述if-else-endif的用途,它甚至可能有用 例如: 变量测试=123
_f_equal_literal some_register,some_value,testing_something
...
_lse testing_something
...
_ndif testing_something
我用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#v(name)
和u-true#v(name):
标签,您只需考虑是否需要btfss
或btfsc
您可以有一个\u lse
和\u ndif
宏,也可以有多个\u f
语句的宏
GJ的解决方案没有next
标签,因此true分支将执行false分支
您需要为每个if-else-endif构造定义一个变量。 如果变量名描述if-else-endif的用途,它甚至可能有用 例如: 变量测试=123
_f_equal_literal some_register,some_value,testing_something
...
_lse testing_something
...
_ndif testing_something
我认为一个人可以做得更好一点。这里有一些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
我认为一个人可以做得更好一点。这里有一些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
我知道,到处跳跃不是一个好主意,但我需要对程序有更高层次的理解。您的解决方案只是部分有用,它没有下一个goto_,因此真正的分支不会执行错误的分支。我在答案中找到了解决办法below@titus问题是没有到处跳跃。问题是宏被展开,导致程序的不同部分存在多个同名标签。因此,当您跳转到具有该名称的标签时,您可以跳转到其中任何一个,而不一定是您想要的!就像这样的代码:
someLabel:retlw d'1'
someLabel:retlw d'2'
当你调用someLabel
时,不清楚你实际上在哪里跳转。@wallacolo我必须注意,共同响应的语句有相同的标签,我知道,到处跳转不是一个好主意,但是我需要这个结构来对程序有更高层次的理解。您的解决方案只是部分有用,它没有下一个goto_,因此真正的分支不会执行错误的分支。我在答案中找到了解决办法below@titus问题是没有到处跳跃。问题是宏被展开,导致程序的不同部分存在多个同名标签。因此,当您跳转到具有该名称的标签时,您可以跳转到其中任何一个,而不一定是您想要的!就像这样的代码:someLabel:retlw d'1'
someLabel:retlw d'2'
当你调用someLabel时,你不清楚你实际上跳到了哪里。@wallacolo我必须注意,共同响应的语句有相同的标签