一、重复汇编
程序中有时需要连续的重复一段相同或者基本相同的语句,这时可以使用重复汇编来完成,重复汇编伪指令有3条:REPEAT/FOR/FORC(在MASM5.x版本依次是REPT/IRP/TRPC),都要用ENDM结束。重复汇编结构既可以在宏定义体外,也可以在宏定义体内。重复汇编的程序段没有名字,但可以有参数。
1、按参数数值重复伪指令REPEAT
REPEAT伪指令的功能是按照设定的重复次数连续重复汇编重复体的语句,格式:
REPEAT 重复次数
重复体
ENDM
例29.1:定义26个大写字母
char = 'A'
AZtable equ this byte
REPEAT 26
db char
char = char + 1
ENDM
汇编结果将是:
AZtable equ this byte
1 db char
1 char = char + 1
1 db char
1 char = char + 1
...
1 db char
1 char = char + 1
2、按参数个数重复伪指令FOR
FOR伪指令的功能是按照实参表的参数个数连续重复汇编重复体的语句。实参表有尖括号括起,参数以逗号分隔,按照参数从左到右的顺序,每次的重复把重复体中的形参用一个实参取代。格式:
FOR 形参,<实参表>
重复体
ENDM
例29.2:保护查功能用寄存器
FOR regad,<ax,bx,cx,dx>
push regad
ENDM
汇编后产生的代码:
1 push ax
1 push bx
1 push cx
1 push dx
3、按参数字符个数重复伪指令FORC
FORC伪指令的功能是按字符串的字符个数连续重复汇编重复体的语句。字符串用或不用尖括号括起,按照字符从左到右的顺序,每次的重复把重复体中的形参用一个字符取代。格式:
FORC 形参,字符串
重复体
ENDM
例29.3:恢复常用寄存器
FORC regad,dcba
pop ®ad&x
ENDM
汇编后产生代码:
1 pop dx
1 pop cx
1 pop bx
1 pop ax
二、条件汇编
条件汇编伪指令根据某种条件确定是否汇编某段语句序列,一般格式:
IFxx 表达式
分支语句体1
[ELSE
分支语句体2
ENDIF
IF后的xx表示组成条件汇编伪指令的其他字符。具体指令如下表:
例:29.4:定义一个元素个数不超过100的数组
pdata macro num
IF num lt 100
db num dup(?)
ELSE
db 100 dup(?)
ENDIF
endm
调用实例:
pdata 12 ;宏调用
db 12 dup(?) ;汇编结果
pdata 102 ;宏调用
db 100 dup(?) ;汇编结果
例29.5:编写宏MAXNUM,计算3个以内的数(形参)中的最大值,并将结果送入AX寄存器,要求根据宏调用时的实参个数展开相应的代码。
分析:实际参加比较的数应该至少有一个,所以第一个参数设定为不可缺省(:req)。如果只有两个参数,则只需要比较一次,后一个比较的代码不用展开。
maxnum macro wx:req,wy,wz
local maxnum1,maxnum2
mov ax,wx
IFNB<wy>
cmp ax,wy
jge maxnum1
mov ax,wy
ENDIF
maxnum1:
IFNB<wz>
cmp ax,wz
jge maxnum2
mov ax,wz
ENDIF
maxnum2:
endm
宏调用实例:
maxnum bx ;宏调用
mov ax,bx ;宏展开结果
maxnum 3,4 ;宏调用
mov ax,3 ;宏展开
cmp ax,4
jge ??0002
mov ax,4
??0002:
maxnum n1,n2,n3 ;宏调用
mov ax,n1 ;宏展开
cmp ax,n2
jge ??0004
mov ax,n2
??0004:
cmp ax,n3
jge ??0005
mov ax,n3
??0005:
条件汇编伪指令虽然与条件控制伪指令(前有一个点符号)从形式上看相似,当他们是不同的。条件汇编伪指令对于分支体的取舍是静态的,是在程序执行前的汇编阶段完成的,执行程序中只有两只分支中的一支,程序执行时不再需要条件判断;而条件控制伪指令组成的程序段对两分支均要汇编,产生相应的指令并被包含在程序中,由程序执行时在执行相应条件的判断,从而执行其中的一支分支,它对分支的选择是动态的。至此,我们可以理解,汇编系统中有些以圆点起始的伪指令(如.startup、.exit、.if等)实际上是一种宏结构。
例29.6:用宏结构实现信息显示
dstring macro string
db '&string&',0dh,0ah,'$'
ENDM
mainbegin macro dsseg
mov ax,dsseg
mov ds,ax
ENDM
mainend macro retnum
ifb<retnum>
mov ah,4ch
else
mov ax,4c00h + (retnum AND 0ffh)
endif
int 21h
ENDM
dispmsg macro message
mov dx,offset message
mov ah,09h
int 21h
ENDM
.model small
.stack 256
.data
msg1 equ this byte
dstring <Hello,World!!>
msg2 equ this byte
dstring <You See,I made it.>
.code
start: mainbegin @data
dispmsg msg1
dispmsg msg2
mainend
end start