📄 masm4.htm
字号:
<html>
<head>
<title>汇编指令的格式(宏指令)</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body bgcolor="#CCCCCC">
<div align="center"></div>
<ol>
<ol>
<div align="center"><b><font face="黑体" lang="ZH-CN" size=4>第六节</font><font face="Arial" size=4>
</font><font face="黑体" lang="ZH-CN" size=4>宏</font><font face="Arial" size=4>
</font><font face="黑体" lang="ZH-CN" size=4>指</font><font face="Arial" size=4>
</font><font face="黑体" lang="ZH-CN" size=4>令</font><font face="黑体" lang="ZH-CN" size=4>
</font> </b> </div>
<p></p>
<font face="宋体" lang="ZH-CN" size=3>
<p align="JUSTIFY"></p>
</font>
<p align="JUSTIFY"><font face="Arial" size=3> </font><font face="宋体" lang="ZH-CN" size=3>宏指令是汇编功能的另一种扩充。在我们编写程序时,常常会遇到这种情况:一些程序段它们的结构相同,但在不同情况下使用的参数不同,这时可以把那变化的参数定义为形参,采用宏指令的方法来解决。在汇编时,汇编程序将填入相应的实参,把它们逐条汇编并生成到相应的程序中去。</font></p>
<p align="JUSTIFY"><font face="Arial" size=3> </font><font face="宋体" lang="ZH-CN" size=3>一个宏指令是汇编语句的一个代码段,其中可以包含有形参,所谓形参是指它的值由引用宏指令时定义,在编写宏指令时它仅仅是一个符号而已。每个宏指令都有一个宏指令名,在程序中可以通过引用它的名字以及给定所需要的参数使用它。宏指令通在汇编语句的命令中使用,参数出现在参数部分中,宏指令每次在程序中引用时,通过实参对形参的替换,使程序中宏指令中的形参获得实际值。一个宏指令必须在它的第一次使用之前被定义。通常,所有的宏指令的定义都集中在程序的首部,宏指令的定义格式如下:</font></p>
<p align="JUSTIFY"><font face="Arial" size=3> </font><font face="宋体" lang="ZH-CN" size=3>宏指令名</font><font face="Arial" size=3>
</font><font face="宋体" lang="ZH-CN" size=3>MACRO</font><font face="Arial" size=3>
</font><font face="宋体" lang="ZH-CN" size=3>形参表</font></p>
<p align="JUSTIFY"><font face="Arial" size=3> </font><font face="宋体" lang="ZH-CN" size=3>(宏指令体)</font></p>
<p align="JUSTIFY"><font face="Arial" size=3> </font><font face="宋体" lang="ZH-CN" size=3>ENDM</font></p>
<p align="JUSTIFY"><font face="Arial" size=3> </font><font face="宋体" lang="ZH-CN" size=3>MACRO和ENDM语句是宏指令定义的标志,它们指出了宏指令的首部和尾部。每个MACRO语句必须有一个匹配的ENDM语句。这些语句不使用标号。</font></p>
<p align="JUSTIFY"><font face="Arial" size=3> </font><font face="宋体" lang="ZH-CN" size=3>宏指令名按照汇编程序中的其它符号名约定,宏指令名被加到汇编程序符号表中,并赋给一个宏指令类型。因而它必须有唯一的名字。其名字将包括在汇编程序列表输出的汇编符号清单中。</font></p>
<p align="JUSTIFY"><font face="Arial" size=3> </font><font face="宋体" lang="ZH-CN" size=3>形参表是在宏指令定义中使用的形参集合。这些参数用符号表示,且仅仅在宏指令定义中使用,而不被加到汇编符号表中。它们只能在宏指令中的代码块中使用。各个形参在参数表中应该用逗号隔开。宏汇编中,每个宏指令最多可支持40个参数。但是,参数表必须与MACFO指令在同一行上,由于每一代码行最大长度为80个字符,因形参的数量也受这个条件限制,参数表是任选的,所以一个宏指令也可以是无参的。</font></p>
<p align="JUSTIFY"><font face="Arial" size=3> </font><font face="宋体" lang="ZH-CN" size=3>宏指令是程序块,它可以是任何汇编语言或伪指令,但由于汇编程序不支持嵌套的宏指令,因此,在宏指令体内不能再使用宏指令或对其他宏指令进行定义。形参可以在代码段语句的任何域中使用,包括标号、命令、参数和注解。形参经常被用作为参数,但是也有可以在其它域中使用。</font></p>
<p align="JUSTIFY"><font face="Arial" size=3> </font><font face="宋体" lang="ZH-CN" size=3>一个宏指令的主要特点是形参的使用。当宏指令在程序段中被调用时,调用处的实际参数替换定义中的形参。因此,宏指令每次被调用时,通过使用时提供的一个唯一的实际参数集,就生成一个唯一的代码段。一个简单的宏指令定义如下所示:</font></p>
<i><font face="Arial" size=3>
<p align="JUSTIFY"> ABC MACRO P1,P2,P3</p>
<p align="JUSTIFY"> MOV A,P1</p>
<p align="JUSTIFY"> MOV R4,P2</p>
<p align="JUSTIFY"> P3</p>
<p align="JUSTIFY"> DEC R5</p>
<p align="JUSTIFY"> ENDM</p>
<p align="JUSTIFY"> JK MACRO P1,X5,OPC1,ARG1,ARG2</p>
<p align="JUSTIFY"> INC X5</p>
<p align="JUSTIFY"> MOV A,P1</p>
<p align="JUSTIFY"> OPC1 ARG1,ARG2</p>
<p align="JUSTIFY"> ENDM</p>
<p align="JUSTIFY"></p>
<p align="JUSTIFY"> CLR A</p>
<p align="JUSTIFY"> MOV R3,A</p>
<p align="JUSTIFY"> ABC R2,#25H,INC R3</p>
<p align="JUSTIFY"> NOP</p>
<p align="JUSTIFY"> JK @R0,R2,ADD,A,R6</p>
<p align="JUSTIFY"> NOP</p>
<p align="JUSTIFY"> ABC #4FH,#39H,DEC A</p>
<p align="JUSTIFY"> NOP</p>
<p align="JUSTIFY"> END</p>
</font></i>
<p align="JUSTIFY"><font face="Arial" size=3> </font><font face="宋体" lang="ZH-CN" size=3>该程序中前部是两个宏指令定义,前一个宏指令为ABC,第二个为JK。后部为主程序,在主程序中ABC、JK分别被引用。汇编后的列表文件如下:</font></p>
<i><font face="Arial" size=3>
<p align="JUSTIFY">The Cybernetic Micro Systems 8051 Family Assembler, Version
3.03 Page 1</p>
<p align="JUSTIFY"> 08-27-96</p>
<p align="JUSTIFY"> ABC MACRO P1,P2,P3</p>
<p align="JUSTIFY"> MOV A,P1</p>
<p align="JUSTIFY"> MOV R4,P2</p>
<p align="JUSTIFY"> P3</p>
<p align="JUSTIFY"> DEC R5</p>
<p align="JUSTIFY"> ENDM</p>
<p align="JUSTIFY"> JK MACRO P1,X5,OPC1,ARG1,ARG2</p>
<p align="JUSTIFY"> INC X5</p>
<p align="JUSTIFY"> MOV A,P1</p>
<p align="JUSTIFY"> OPC1 ARG1,ARG2</p>
<p align="JUSTIFY"> ENDM</p>
<p align="JUSTIFY"></p>
<p align="JUSTIFY"> 0000 E4 CLR A</p>
<p align="JUSTIFY"> 0001 FB MOV R3,A</p>
<p align="JUSTIFY"> 0002 ABC R2,#25H,INC R3</p>
<p align="JUSTIFY">+0002 EA MOV A,R2</p>
<p align="JUSTIFY">+0003 7C25 MOV R4,#25H</p>
<p align="JUSTIFY">+0005 0B INC R3</p>
<p align="JUSTIFY">+0006 1D DEC R5</p>
<p align="JUSTIFY"> 0007 00 NOP</p>
<p align="JUSTIFY"> 0008 JK @R0,R2,ADD,A,R6</p>
<p align="JUSTIFY">+0008 0A INC R2</p>
<p align="JUSTIFY">+0009 E6 MOV A,@R0</p>
<p align="JUSTIFY">+000A 2E ADD A,R6</p>
<p align="JUSTIFY"> 000B 00 NOP</p>
<p align="JUSTIFY"> 000C ABC #4FH,#39H,DEC A</p>
<p align="JUSTIFY">+000C 744F MOV A,#4FH</p>
<p align="JUSTIFY">+000E 7C39 MOV R4,#39H</p>
<p align="JUSTIFY">+0010 14 DEC A</p>
<p align="JUSTIFY">+0011 1D DEC R5</p>
<p align="JUSTIFY"> 0012 00 NOP</p>
<p align="JUSTIFY"> 0000 END</p>
<p align="JUSTIFY">The Cybernetic Micro Systems 8051 Family Assembler, Version
3.03 Page 2</p>
<p align="JUSTIFY"> 08-27-96</p>
<p align="JUSTIFY"> ;%T Symbol Name Type Value</p>
<p align="JUSTIFY"> ABC . . . . . . . . . . . . . . M 0000</p>
<p align="JUSTIFY"> JK. . . . . . . . . . . . . . . M 0000</p>
<p align="JUSTIFY"> ;%Z</p>
<p align="JUSTIFY"> 00 Errors (0000)</p>
</font></i><font face="Arial" size=3>
<p align="JUSTIFY"> </p>
</font>
<p align="JUSTIFY"><font face="Arial" size=3> </font><font face="宋体" lang="ZH-CN" size=3>在列表文件中,在调用宏指令处,实参数被充填到宏指令的形参处,并把宏指令体扩充到程序中形成代码。在这个例子中实参不仅代替了指令中的参数部分,而且还能代替整个指令。文件中最前列带“+”的语句为引用宏指令扩展的部分。宏指令被引用时,参数表上实参表应与所替代的形参相对应。在表中出现的参数必须用逗号隔开,汇编程序取逗号之间或与第一个逗号之间,或最后一个逗号与行尾之间的任何字符作为实际参数。这样,可以使用多个符号,甚至一个整条指令作为一个参数,只要在数中没有逗号就行。一个逗号不能作为一个参数的一部分被传递。汇编程序将滤去每个参数的前面和后面的空格,仅仅保留第一个到最后一个可打印字符。</font></p>
<p align="JUSTIFY"><font face="Arial" size=3> </font><font face="宋体" lang="ZH-CN" size=3>此外,宏指令的实际参数表可以不与形参表完全匹配,即实际参数的数量可以多于或少于形参表中的形参个数。当参数空缺时,相应的形参在宏扩展时被取消,如果实际参数比形参多,则多余的实际参数将被忽略。最后一个在表中间的参数可以通过在参数表中间放两个逗号来赋空值。参见下面的例子。</font></p>
<i><font face="Arial" size=3>
<p align="JUSTIFY"> ABC MACRO P1,P2,P3</p>
<p align="JUSTIFY"> MOV A,P1</p>
<p align="JUSTIFY"> MOV R4,P2</p>
<p align="JUSTIFY"> P3</p>
<p align="JUSTIFY"> DEC R5</p>
<p align="JUSTIFY"> ENDM</p>
<p align="JUSTIFY"></p>
<p align="JUSTIFY"> JK MACRO P1,X5,OPC1,ARG1,ARG2</p>
<p align="JUSTIFY"> INC X5</p>
<p align="JUSTIFY"> MOV A,P1</p>
<p align="JUSTIFY"> OPC1 ARG1,ARG2</p>
<p align="JUSTIFY"> ENDM</p>
<p align="JUSTIFY"></p>
<p align="JUSTIFY"> NOP</p>
<p align="JUSTIFY"> JK #33H,R3,NOP</p>
<p align="JUSTIFY"> SWAP A</p>
<p align="JUSTIFY"> NOP </p>
<p align="JUSTIFY"> JK R4,R2,ADDC,A,@R1,#66H</p>
<p align="JUSTIFY"> NOP</p>
<p align="JUSTIFY"> JK #40H,R4,,DEC R2</p>
<p align="JUSTIFY"> NOP</p>
<p align="JUSTIFY"> END</p>
</font></i>
<p align="JUSTIFY"><font face="Arial" size=3> </font><font face="宋体" lang="ZH-CN" size=3>宏指令的另一个特点是形参可以被用作一个标号,如果一个形参被用作一个标号,当引用宏指令时,实参将成为标号。这就要求每次宏指令调用时,该实参不能相同。以避免标号重复定义错误。例:</font></p>
<i><font face="Arial" size=3>
<p align="JUSTIFY">The Cybernetic Micro Systems 8051 Family Assembler, Version
3.03 Page 1</p>
<p align="JUSTIFY"> 08-27-96</p>
<p align="JUSTIFY"> ABC MACRO P1,P2,P3</p>
<p align="JUSTIFY"> MOV A,P1</p>
<p align="JUSTIFY"> MOV R4,P2</p>
<p align="JUSTIFY"> P3</p>
<p align="JUSTIFY"> DEC R5</p>
<p align="JUSTIFY"> ENDM</p>
<p align="JUSTIFY"></p>
<p align="JUSTIFY"> JK MACRO P1,X5,OPC1,ARG1,ARG2</p>
<p align="JUSTIFY"> INC X5</p>
<p align="JUSTIFY"> MOV A,P1</p>
<p align="JUSTIFY"> OPC1 ARG1,ARG2</p>
<p align="JUSTIFY"> ENDM</p>
<p align="JUSTIFY"></p>
<p align="JUSTIFY"> 0000 00 NOP</p>
<p align="JUSTIFY"> 0001 JK #33H,R3,NOP</p>
<p align="JUSTIFY">+0001 0B INC R3</p>
<p align="JUSTIFY">+0002 7433 MOV A,#33H</p>
<p align="JUSTIFY">+0004 00 NOP ,</p>
<p align="JUSTIFY"> 0005 C4 SWAP A</p>
<p align="JUSTIFY"> 0006 00 NOP</p>
<p align="JUSTIFY"> 0007 JK R4,R2,ADDC,A,@R1,#66H</p>
<p align="JUSTIFY">+0007 0A INC R2</p>
<p align="JUSTIFY">+0008 EC MOV A,R4</p>
<p align="JUSTIFY">+0009 37 ADDC A,@R1</p>
<p align="JUSTIFY"> 000A 00 NOP</p>
<p align="JUSTIFY"> 000B JK #40H,R4,,DEC R2</p>
<p align="JUSTIFY">+000B 0C INC R4</p>
<p align="JUSTIFY">+000C 7440 MOV A,#40H</p>
<p align="JUSTIFY">+000E 1A DEC R2,</p>
<p align="JUSTIFY"> 000F 00 NOP</p>
<p align="JUSTIFY"> 0000 END</p>
<p align="JUSTIFY"></p>
<p align="JUSTIFY">The Cybernetic Micro Systems 8051 Family Assembler, Version
3.03 Page 2</p>
<p align="JUSTIFY"> 08-27-96</p>
<p align="JUSTIFY"> ;%T Symbol Name Type Value</p>
<p align="JUSTIFY"> ABC . . . . . . . . . . . . . . M 0B0D</p>
<p align="JUSTIFY"> JK. . . . . . . . . . . . . . . M 0000</p>
<p align="JUSTIFY"> ;%Z</p>
<p align="JUSTIFY"> 00 Errors (0000)</p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -