Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4595132
  • 博文数量: 671
  • 博客积分: 10010
  • 博客等级: 上将
  • 技术积分: 7310
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-14 09:56
文章分类

全部博文(671)

文章存档

2011年(1)

2010年(2)

2009年(24)

2008年(271)

2007年(319)

2006年(54)

我的朋友

分类:

2007-04-16 10:15:41

宏汇编:
什么是宏?
     宏(或宏指令)是源程序中一段有独立功能的程序代码,只需定义一次,可以多次调用
为什么使用宏汇编?
         在编制汇编语言程序过程中,有些功能程序段需要多次重复使用,所不同的只是参与操作的操作数。
    为了减少编程的工作量,通常采用两种方法:
①将程序段编写为独立的子程序
②将程序段定义成宏
大家想一下 子程序有什么优缺点?
宏定义、宏调用和宏展开 :
1.宏定义
       用伪指令MACRO/ENDM实现,其语句格式是:
宏指令名 MACRO    [形参1,形参2,…,形参n]
           ┇   宏定义体
                      ENDM
宏指令名是该宏定义的名称。调用时使用宏指令名对该宏定义进行调用。
宏指令符合标识符规定。宏指令名不能重复,并且指令的第一个字符必须是字母。但可以和源程序中的其他变量、标号、指令、伪指令名相同,在这种情况下宏指令的优先级最高。
   MACRO必须与ENDM成对出现。MACRO标识宏定义的开始 。

形式参数(即形参,也称哑元、虚参)是可选项,宏可以不带参数;带参数时,多个形参间用逗号分隔
2.宏调用
宏调用的格式为:
     宏指令名   [实参1,实参2,…,实参n]        
说明:实参可以是常数、寄存器、存储单元、地址表达式、指令的操作码或者是操作码的一部分
3.宏展开
       宏展开就是宏定义体取代源程序中的宏指令名,而且用实元取代哑元。汇编源程序时,宏汇编程序将对每条宏指令语句进行宏展开,用实参替代相应的形参,对宏体目标代码作相应改变。
  
子程序调用和宏调用的工作方式:
用一个例子来说明宏定义、宏调用和宏展开的情况
例:将两个16位数相加,结果存入16位 RESULT 单元中 。
;对两数相加功能进行宏定义
BCDADD MACRO VARX,VARY,RESULT   
        MOV AL,VARX                               
        ADD AL,VARY
        MOV RESULT,AL
        MOV AL,VARX+1
        ADC AL,VARY+1
        MOV RESULT+1,AL
        ENDM
DATA   SEGMENT
       A1     DW    1234H
       A2     DW    5678H
       A3     DW    ?
       B1     DW    1357H
       B2     DW    2468H
       B3     DW    ?
DATA   ENDS
CODE   SEGMENT
       ASSUME CS:CODE,DS:DATA
START:PUSH   DS
       MOV    AX,0
       PUSH   AX            
MOV   AX,DATA
      MOV    DS,AX
      BCDADD A1,A2,A3;宏调用
      BCDADD B1,B2,B3   ;再次宏调用
       RET
CODE   ENDS
       END     START
经宏展开后:
       PUSH   DS
       MOV    AX,0
       PUSH   AX
       MOV    AX,DATA
       MOV    DS,AX
MOV   AL,A1
1       ADD   AL,A2
1       MOV   A3,AL
1       MOV   AL,A1+1
1       ADC   AL,A2+1
     MOV   A3+1,AL
1       MOV   AL,B1                
1       ADD   AL,B2   
1       MOV   B3,AL
1       MOV   AL,B1+1
     ADC   AL,B2+1
MOV   B3+1,AL

   宏汇编程序在所展开的指令前标识以‘1’号以示区别。较早的版本用‘+’
宏定义中的参数:
1 宏定义可以无参数
savereg   macro
              push   ax
              push   bx
              push   cx
              push    si
              endm
2   参数可以是操作码
a   macro    p1, p2,p3
       mov   ax,p1
       p2      p3
       endm
调用:
     a    word_ var ,inc,ax
展开:
   mov    ax,word_var
1       inc    ax
3   参数可以是操作码或操作数的一部分,但在宏定义体中必须使用分隔符&,即&是操作符,在宏定义中可作为形参的前缀,展开时把&前后的两个符号连接起来,形成操作码、操作数或字符串。&只能出现在宏定义中。
4 伪操作%不能出现在形参的前面,通常用在宏调用中,将跟在它后面的表达式的值转换成以当前基数下的数,在宏展开时,用转换后的值代替形参。
伪指令 LOCAL :
宏定义体内可以使用标号。对于使用了标号的宏定义,若多次调用,势必产生标号的多重定义,汇编时出错。解决这一问题可使用伪指令LOCAL,其一般格式为:
   LOCAL    局部标号1,局部标号2,…
     宏汇编程序将为标号分别生成格式为“??XXXX”的唯一的符号以代替各局部标号。XXXX代表四位十六进制数0000~FFFF。这样,在汇编源程序中,避免了多次宏调用时生成的标号重复。
注意:LOCAL伪操作只能用在宏定义体内,而且必须是MACRO伪操作后的第一个语句,在MACRO与LOCAL不能出现注释和分号标志。
  
在宏定义内使用宏:
宏定义中允许使用宏调用,限制条件是:必须先定义

列表伪操作:
Masm提供了.xall , .lall, sall来控制汇编清单中宏展开的列出情况
.xall   为默认情况,它指示清单中只列出产生目标        代码的宏展开;
.lall   列出包括注释在内的所有宏展开;
.sall   则不列出任何信息;
宏库的建立与调用:
如果程序中定义了很多宏,可以把这些宏组合起来建立一个独立的文件,这个只包含若干个宏定义的文件称为宏库。扩展名是mac 或inc来表示。当需要使用宏库中的某些宏定义时,只需要在该程序的开始用INCLUDE语句说明
           INCLUDE    C:\MACRO.MAC
伪指令PURGE:
宏汇编程序提供了伪操作PURGE,用来在适当的时候取消宏定义。
PURGE伪指令的一般格式是:
      PURGE    宏定义名[,…]
     方括号表示PURGE可以取消多个宏定义,宏名之间用逗号隔开。如宏定义:
   SUB   MACRO   VARX,VARY,RESULT
        ┇
        ENDM
宏调用:SUB     X,Y,Z
        PURGE SUB

 

 


重复汇编:
有时汇编语言程序要连续地重复完成相同或者几乎完全相同的一组代码,这时可用重复汇编。
定重复伪指令REPT
其一般格式为:
    REPT   表达式
        ┇ (重复块 )
    ENDM
    其中,REPT和ENDM必须成对出现,两者间的重复块是要重复汇编的部分。表达式的值用来表示重复块的重复汇编次数。重复伪操作不一定要用在宏定义体内。
不定重复伪指令IRP :
其一般格式为:
     IRP      形参,〈参数1,参数2,…〉
      ┇    (重复块)
     ENDM
     此伪指令重复执行重复块中所包含的语句,重复的次数由参数表中的参数个数决定。重复汇编时,依次用参数表中的参数取代形参,直到表中的参数用完为止。参数表中的参数必须用两个三角号括起来,参数可以是常数、符号、字符串等,各参数间用逗号隔开。
不定重复字符伪指令IRPC :
其语句格式为:
     IRPC    形参,字符串(或〈字符串〉)
       ┇    (重复块)
     ENDM
         
     此伪指令重复执行重复块中的语句,重复汇编的次数等于字符串中字符的个数。每次重复执行时,依次用字符串中的一个字符取代形参,直到字符串结束。可见IRPC伪指令与IRP伪指令类似,只是IRPC用字符串(其三角括号可以有也可以无)代替了IRP伪指令中的参数表。
条件汇编:
汇编程序能根据条件把一段源程序包括在汇编语言程序内的或排除在外,这里就用到条件伪操作。条件伪操作的一般格式是:
Ifxx             argument
┇                ;自变量满足条件汇编此块
[ELSE]
┇                ;自变量不满足条件汇编此块
ENDIF
说明:汇编程序在对源程序汇编时,要对源程序扫描二遍 。第一遍建立符号表 ,第二遍才把汇编语言指令翻译成机器语言指令。那么自变量必须在汇编程序第一遍扫视后就成为确定的数值。
IF   expression           ; 汇编程序求出表达式的值,如此值不为0,      则 满足条件.
IFE   expression          ;汇编程序求出表达式的值,如此值为0,则                                                                                   满足条件.
IF1             ;在汇编程序的第一遍扫视期间满足条件
IF2             ;在汇编程序的第二遍扫视期间满足条件
   说明:汇编程序在对包括宏库的源程序汇编时也分两次扫描,第一次将宏库及程序中的宏定义登入宏定义表,第二次 扫描时进行宏扩展,形成列表文件。
  大家看书上268页的例7.24,然后和259页的例7.12比较看有什么不同?
   IFB        ;如自变量为空,则满足条件
   IFNB       ;如自变量不为空,则满足条件
注意:自变量用“<   >”括起来
IFDEF   symbol     ;如符号已在程序中定义,或者用extrn说明该符号是在外部定义的,则满足条件。
IFNDEF   symbol     ;如符号未定义或未通过EXTRN说明为外部符号则满足条件。
IFIDN ,     ;如果字符串和字符串相同,则满足条件。
IFDIF ,     ;如果字符串和字符串不相同,则满足条件。
 在格式中,两个参数必须用尖括号括起
阅读(5774) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~