重复伪指令REPEAT
重复伪指令REPEAT与前面9.4.1节中伪指令REPT在功能和使用方式方面完全一致,设置该伪指令的主要原因是保证与先前版本的兼容性。
伪指令REPEAT的使用方式如下:
REPEAT |
数值表达式 |
|
语句序列 |
;被重复的汇编语言语句 |
|
ENDM |
9.6.3 循环伪指令WHILE
循环伪指令WHILE的使用方式如下:
WHILE |
Exp |
|
语句序列 |
;被重复的汇编语言语句 |
|
ENDM |
其功能是先判断表达式Exp是否为假(或为0),若是,则终止该伪指令的功能,否则,循环汇编下面的指令块。表达式Exp是能在汇编时计算出其值的数值表达式。
例9.16:编写一个带有参数result和k的宏,其功能是把1 2 … k的累加和存入result之中,其中:result是不可缺省的,k的缺省值为1。
解:
SUM |
MACRO result:REQ, k:=<1> |
|
LOCAL n |
||
n = k |
||
mov |
result, 0 |
|
WHILE |
n |
|
add result, n n = n - 1 ENDM |
||
ENDM |
有了上面的宏定义,就可书写下面的宏引用来实现其相应的功能:
|
SUM |
ax, 10 |
;寄存器ax=1 2 3 … 10 |
SUM |
bh |
;寄存器bh=1,因为第二个形参取其缺省值 |
|
SUM |
ecx, 100 |
;寄存器ecx=1 2 3 … 100 |
|
SUM |
data, 20 |
;存储单元data=1 2 3 … 20 |
9.6.4 循环伪指令FOR
循环伪指令FOR与9.4.2节中伪指令IRP在功能上完全一致,设置该伪指令的原因也是为了保证与先前版本的兼容性。
伪指令FOR的使用方式如下:
其中各参数的说明如下:
FOR |
parameter[:REQ|:=<default>], <argument [, argument]...> |
|
语句序列 |
;被重复的汇编语言语句 |
|
ENDM |
例如:
parameter |
一个合法的标识符,它依次取后面参数表中的值。在指令序列中,该变量的每次出现都用其值所替换; |
:REQ |
说明该变量的取值不能为空; |
:=<default> |
指定该变量的缺省值,若后面的参数表缺省某个参数(用连续的逗号),这时,该循环变量将取其缺省值; |
Argument |
参数表中可含有文本、符号、字符串或数值常量,每个参数之间要用逗号分割。 |
FOR |
data:=<?>, <"123", , 21, 0> |
DB data |
|
ENDM |
|
…… |
|
FOR |
reg:REQ, <ax, bx, dx> |
push reg |
|
ENDM |
该语句在宏展开时,将得到下列语句:
DB "123"
DB ?
DB 21
DB 0
……
push ax
push bx
push dx
9.6.5 循环伪指令FORC
循环伪指令FOR与9.4.3节中伪指令IRPC在功能上完全一致,它也是为保证与先前版本的兼容性而设置的。
伪指令FORC的使用方式如下:
其中各参数的说明如下:
例如:
FORC |
parameter, <string> |
|
语句序列 |
;被重复的汇编语言语句 |
|
ENDM |
该语句在宏展开时,将得到下列语句:
DB 1
DB ?
DB 3
……
push ax
push bx
push dx
9.6.6 转移伪指令GOTO
转移伪指令GOTO用于实现宏定义体内的转移功能,其使用方式如下:
GOTO 标号
…
:标号 ;标号后不能写指令,但可写注释
…
该伪指令的功能是使汇编程序转移到“标号”处汇编,它只能在宏定义MACRO、REPEAT、WHILE、FOR和FORC等语句块内使用,该标号也只在该语句块内有效。
9.6.7 宏扩充的举例
例9.17:编写一个给任意寄存器或存储单元清零的宏定义。
解:
parameter: |
一个合法的标识符,它依次取字符串中的每个字符。在语句序列中,该变量的每次出现都用其值所替换; |
String: |
一个字符串或被定义为字符串的符号名,字符串中的空格也被算为一个字符。括号"<"、">"是必不可少的。 |
FORC |
data, <1?3> DB data ENDM |
…… |
|
FORC |
reg, <abd> push reg&x ENDM |
有了上面的宏定义,下面的二个宏引用都是正确的,尽管宏引用时所带的参数个数是不同的。这正是参数属性VARARG的作用所在。
Clear ax, bx
……
Clear si, cl, MemVar, edx ;MemVar是内存变量,任意类型都可以
这二个宏引用展开时所得到的指令如下:
mov ax, 0
mov bx, 0
……
mov si, 0
mov cl, 0
mov MemVar, 0
mov edx, 0