1、1,第八章 高级宏汇编语言,8.1 结构,结构就是将逻辑上有一定关系的一组数据,以某种方式组合在一起所形成的数据形式。,比如,将学生的学籍档案以结构的数据形式来表示。每个学生的各种数据,如姓名、学号、年龄和各科成绩等等,组成了一个结构型数据。,一、结构的定义,结构的定义使用结构伪指令,其格式为:,结构名 STRUC 结构名 ENDS,2,在一个源程序中结构名必须是唯一的。数据定义语句序列是用DB、DW或DD定义的变量,作为结构中的各字段(Fields),所定义的各变量名称为结构字段名。,例如: STUDENT STRUC CLASS DB 26060010 NUM DB ? NAME DB 1
2、5 DUP(?) SCORE DB ? STUDENT ENDS,注意:使用伪指令STRUC/ENDS定义的结构不产生目标代码,而定义的各个字段也不分配存储单元。,3,二、结构的预置与存储分配,其中:结构名使用STRUC/ENDS定义的结构。结构变量名是结构副本的标识符,与其它变量一样,它也有三个属性:段、偏移量和类型属性。类型属性表示结构的总字节数。,结构预置: 用定义的结构预置副本,设置结构变量,分配存储空间。,结构变量名 结构名 ,结构变量预置语句的格式为:,字段值表是为结构副本中各字段的值进行预置,必须用一对尖括号括起来。,4,例如: DATA SEGMENT STU1 STUDENT
3、 ;不改变结构定义时的初值定义 STU2 STUDENT ;只改变第一个字段的值 STU3 STUDENT ;第一个字段不变,其余重置 STU4 STUDENT 10H DUP() ;同时预置10H个副本,每个副本只修改第一个字段初值。 DATA ENDS,三、对结构变量及其字段的操作,结构变量的使用与一般变量一样,可以作为一条指令的操作数。 注意:TYPE运算符作用结构变量,其返回值为该结构变量的总字节数。,MOV AX,TYPE STU1;AX=25MOV BH,LENGTH STU2;BH=1MOV BL,LENGTH STU4;BL=10HMOV CX,SIZE STU3 ;CX=25
4、MOV DX,SIZE STU4 ;DX=16*25,例如:,5,结构变量的字段的使用与一般变量的使用完全相同。,MOV SI , OFFSET STU1.CLASS ; SI=0MOV DI , OFFSET STU2.CLASS ; DI=25MOV AX, LENGTH STU1. NAME ; AX=15MOV BX, OFFSET STU2MOV BX.SCORE, 80 ;将STU2的SCORE字段赋值80,访问结构变量中的字段要使用结构字段运算符“.”,结构变量名. 结构字段名,其使用格式为:,例如:,6,四、程序举例,BLOCK STRUCFB1 DB ?FB2 DB ?FB3
5、 DW 10H DUP(?)BLOCK ENDSDATA SEGMENTSTRU_VAR BLOCK 20 DUP()DATA ENDS,要求在20个结构变量的FB1字段中依次存入字母A、B、C、D.,在FB2字段中依次存入字母Z、Y、X、W、V、.。主要程序段编制如下:,例1 现有结构定义和预置如下:,MOV DI,OFFSET STRU_VAR ;取结构变量首址 MOV AL,A ;取初始化字段内容 MOV AH,Z MOV CX,LENGTH STRU_VAR ;取结构变量个数LOP:MOV DI.FB1, AL ;依次向字段送字母 MOV DI.FB2, AH INC AL ;修改字段
6、内容 DEC AH ADD DI,TYPE STRU_VAR ;修改指针 LOOP LOP,7,例2 设学生学籍结构为SC1SC7是7个连续字段,分别记载每个学生的7门课程的成绩;AVERAGE字段是该学生的平均成绩。在数据段预置了30位学生的结构副本。另有程序已完成30位学生的成绩录入。要求编制一子程序计算30位学生7门课程的平均成绩并送入相应的AVERAGE字段中。,结构定义和数据段中结构预置如下:,STUD_SCOR STRUC: :SC1 DB 0SC2 DB 0SC3 DB 0SC4 DB 0SC5 DB 0SC6 DB 0SC7 DB 0AVERAGE DB 0STUD_SCOR
7、ENDS:CLA_SCOR STUD_SCOR 30 DUP(),8,SCORE PROC LEA BX,CLA_SCOR;取第一个结构副本首址送BX MOV CX,30 ;计算平均成绩的总人数LOP1: XOR AX,AX PUSH CX LEA SI,BX.SC1;SI8时,汇编程序自动将记录定义为字(16位),否则定义为字节(8位)。,10,根据字段定义的顺序,先定义的在高位,最后定义的字段在最低位。如果各字段之和8或16,则未定义的高位以“0”填充。,REC1 RECORD F1:4,F2:2,F3:6,F4:4REC2 RECORD FE1:2,FE2:4,FE3:1,FE4:1RE
8、C3 RECORD FF1:3,FF2:4,FF3:3,FF4:3 REC4 RECORD FD1:3=100B,FD2:2=2,FD3:1=1,例如:,上述定义的各记录的字段分配如下图所示。,11,记录定义时不分配存储单元,只有当预置了记录时,才分配存储空间。,二、记录的预置与存储分配,其中记录变量名是可选项,如果选用,它就是记录副本的标识符。,记录变量预置语句的格式:,记录变量名 记录名 字段值表 ,12,例如:,DA1 REC1 DA2 REC2 DA3 REC3 5 DUP()DA4 REC4 DA5 REC4 DA6 REC4 10H DUP(),上述各记录预置后,按字节或字分配存储
9、单元。例如对记录变量DA3分配存储单元如下:,在字段值表中未指定初值的字段,用逗号表示,它将使用定义的初值,若定义时未指定值,则用0填入。,13,三、记录运算符,在宏汇编中有几个运算符是专门用于对记录进行操作。,1、记录宽度运算符(WIDTH),WIDTH运算作用于记录名或记录字段名。其运算结果是返回该记录或记录字段的宽度(二进制数的位数)。,NF1 EQU WIDTH REC1 ;NF1=10HNF2 EQU WIDTH F3 ;NF2=06HNF3 EQU WIDTH F4 ;NF3=04H MOV AH,WIDTH REC2;(AH)=08H MOV AL,WIDTH FE1 ;(AL)
10、=02H MOV BH,WIDTH REC3;(BH)=0DH MOV BL,WIDTH FF2 ;(BL)=04H,例如:,14,2. 移位值运算,MOV BL,F1 ;(BL)=0CHMOV BH,F2 ; (BH)=0AHMOV CL,F3 ; (CL)=04HMOV CH,F4 ; (CH)=00H,在语句中如果直接将记录字段名作为一个操作数引用,则表示取该字段的最低位移到所在记录的最低位所需的移位次数。,例如:,3、记录屏蔽运算符,在记录字段名前加上MASK运算符,将返回该记录字段在记录中的屏蔽码。所谓屏蔽码是指该字段的各位为1其余各字段全为0,所构成的编码。,例如:,MOV AX,
11、 MASK F1 ;(AX)=0F000HMOV BL, MASK FE2 ;(BL)=3CHMOV CX, MASK FF3 ;(CX)=38HMOV BH, MASK FD1 ;(BH)=38H,15,四、对记录及其字段的操作,1、对记录变量的操作,MOV AX,DA1 ;取出DA1记录变量的值0AE56H送AXMOV BL,DA2 ;BL = 61HMOV DA3+4,CX ;将CX内容送DA3的第三个记录变量,对预置的记录变量,就可以象普通变量一样进行存取。,例如:,2、对记录操作数的操作,在程序中,可以直接将已经定义的记录名作操作数使用,它被作为一个常数使用,即寻址方式为立即数寻址。
12、 使用时,记录名后必须有一对尖括号。如果括号中无内容,表示使用记录定义时的初值。也可以为各字段重新指定值。,16,MOV AX,REC1 ;对记录REC1的各字段赋值后,其值0BBA7H送AXMOV BL,REC4 ;将记录REC4的FD2和FD3字段清零后,其值20H送BLMOV BH,REC4 ;将记录REC4的原来值送BH,注意未定义的位用0填充MOV CL,REC4+REC4;将20H+25H的值45H送CL,3、对记录字段的操作,由于一个记录字段是一个字节或一个字中的某几位,在处理时,需要将记录变量作为一个整体进行操作。 例如下面的程序段是将记录变量DA1的F2字段取出,并将其移位到
13、最右边。,MOV AX,DA1 ;取记录变量AND AX,MASK F2 ;用屏蔽码分离出F2字段MOV CL,F2 ;取F2的移位值送CLSHR AX,CL,如果要修改记录变量的字段,可先取出,修改后再存回记录变量中。,例如:,17,8.3 宏指令,在汇编源程序设计中,如果要多次重复使用某一个程序段,这些程序段虽然出现位置不同,但功能完全相同,或者只是修改某些操作数字段。这时可使用宏指令来实现。,一. 宏功能的使用过程,宏功能的使用过程包括:宏定义,宏调用和宏展开,使用宏指令可以使源程序更加清晰,易于阅读,简化重复程序的编写。,1. 宏定义,宏定义使用一对伪指令MACRO和ENDM。宏定义格
14、式有两种。,18,(1)不带参数的宏定义,(2)带参数的宏定义,注意:宏定义本身不生成任何目标代码。,2. 宏调用,宏调用就是在源程序的任意位置直接引用已经定义的宏名。所构成的语句称为宏指令语句。,(1)无参数宏调用:宏名(2)带参数宏调用:宏名 实参1,实参2,.,宏调用分为无参数调用和带参数调用,其格式分别为:,19,INPUT MACRO ;定义宏INPUT MOV AH,01H INT 21H AND AL,0FH ENDMEXCHANGE MACRO BY1,BY2 ;定义宏EXCHANGE PUSH AX MOV AL,BY1 XCHG AL,BY2 MOV BY1,AL POP
15、AX ENDM : INPUT ;调用宏INPUT : : EXCHANGE DA_BY1,DA_BY2 ;调用宏EXCHANGE :,例如:,带参数宏调用时,实参与形参的排列顺序应一致。如果实参的个数比形参多,则多余的实参将被略去。如果实参的个数比形参少,则未指定的形参将用“空白串”替代。,20,3. 宏展开,宏展开是指汇编程序在汇编源程序过程中,当扫描到宏指令语句时,将用宏定义中的宏体的程序段目标代码替代宏指令语句。对于带参数的宏调用,将同时用相应的实参替代宏体中对应的形参。,二. 连接符&和带空格或逗号的实参,在宏定义时,可以将形参作为一个字符串中的一部分,这时需要使用连接符&。 在宏调
16、用时,可以在实参中包含空格和逗号字符,这时需要用“”将实参括起来。,21,SHIFT MACRO VAR,REG,SHF,NUM,DEST MOV REG,VAR MOV CL,NUM S&SHF REG,CL ;SHF为形参 MOV DEST,REG ENDM : SHIFT DA_WORD,AX,AR,CONT+1,例如:,上述宏展开后为:,MOV AX,DA_WORDMOV CL,CONT+1SAR AX,CLMOV WORD PTR DEST1+2,AX,22,8.4 重复汇编,使用重复汇编伪指令可以让汇编程序对某些语句序列进行重复汇编。重复汇编指令可以有以下三种。,1. 定重复,M=
17、0NUM=5REPT 5 M=M+1 DB NUM*MENDM,例如:,上述语句经汇编后等效下面的语句:DB 5,0AH,0FH,14H,19H,表达式的值为REPT与ENDM之间的语句序列重复汇编次数,23,2. 不定重复,格式:,IRP与ENDM之间语句序列的重复汇编次数由实参的个数确定,每次重复汇编时,依次用实参表中的实参替代形参。,3. 不定重复字符,格式:,IRPC与ENDM之间的语句序列的重复次数由字符串中字符的个数来确定。每次汇编重复语句序列时,依次用字符串中一个字符替代形参。,24,8.5 条件汇编,使用条件汇编,可以使宏汇编语言源程序中某些部分,在汇编期间按照给定条件产生目标代码或不产生目标代码。,基本格式:,其中:XX为指定的条件,如果在汇编时,指定的条件成立,则将条件块1的语句序列汇编成相应的目标代码,否则汇编条件块2。,ELSE及相应的条件块2为可选项。,25,除了上述基本的条件汇编伪指令外, MASM还提供其他的条件汇编伪指令。如下表所示。,