第七部分宏汇编初步AssemblyLanguageProgramming概要结构记录宏指令条件宏汇编结构结构:逻辑上相互关联的一组数据变量组合在一起模板或者模式。字段:包含数据的结构成员程序对一个结构的访问:–整个结构作为一个整体进行–单个的域注意:这和C/C++中的结构体相似结构的定义nameSTRUCfield-declarationsnameENDS•其中,字段为组成结构的各个内部变量,和普通DB/DW等变量的声明是一样的结构的使用结构的使用涉及到三个步骤:1.定义结构2.声明所定义的结构变量3.程序对结构变量进行相关的操作例:员工结构EmployeeSTRUCIdNumDB000000000LastNameDB30DUP(0)YearsDW0SalaryHistoryDW4DUP(0)EmployeeENDS000000000(null)00000SalaryHistoryLastnameYearsIdnum例:坐标结构COORD结构定义了x,y坐标值COORDSTRUCTXDW?;offset00YDW?;offset02COORDENDS结构变量的声明结构变量名是用户自定义的名称变量名结构名字段值表在...中插入各个字段的值,以逗号间隔空保留结构的初始缺省值例如:.datapoint1COORD5,10point2COORDworkerEmployee初始化使用DUP操作符初始化一个或者多个数组字段元素:empEmployee,,,2DUP(2000)结构数组结构对象的数组使用DUP初始化NumPoints=3AllPointsCOORDNumPointsDUP(0,0)CS_DeptEmployee20DUP()accountingEmployee10DUP(,,,4DUP(2000))结构变量的操作.dataworkerEmployeemovAX,TYPEEmployee;49movAX,SIZEEmployee;49movAX,SIZEworker;49movAX,TYPEEmployee.SalaryHistory;2movAX,LENGTHEmployee.SalaryHistory;4movAX,SIZEEmployee.SalaryHistory;8EmployeeSTRUC;bytesIdNumDB000000000;9LastNameDB30DUP(0);30YearsDW0;2SalaryHistoryDW4DUP(0);8EmployeeENDS;49movdx,worker.Yearsmovworker.SalaryHistory,2000;firstsalarymovworker.SalaryHistory+4,3000;secondsalarymovdx,OFFSETworker.LastNamemovsi,OFFSETworkermovax,(EmployeePTR[si]).Yearsmovax,[si].Years;invalidoperand(ambiguous)例1:p164学生成绩的结构数组–30名学生7门课程的平均成绩编写子程序完成各个学生的平均成绩计算记录记录的概念与定义记录的存储分配和初始化对记录的相关操作概念记录和结构类似,但不同之处是以二进制数的位数bit为字段的基本单位。记录的定义格式记录名RECORD字段名:宽度,字段名:宽度,……–其中宽度是所在字段的二进制数的位数分配空间的规则:–记录的所有字段位数之和不超过16。–不足8位,分配8位;大于8位,不足16位,分配16位。–数据各位填充按右对齐进行。–从第一个字段开始,依次对各个字段从高位到低位分配位数。举例REC1RECORDF1:4,F2:2,F3:6,F4:4REC2RECORDFE1:2,F2E:4,FE3:1,FE4:1REC3RECORDFF1:3,FF2:4,FF3:3,FF4:3REC4RECORDFD1:3=100B,FD2:2=2,FD3:1=1–其中表达式是设定的初值记录变量的声明格式–记录变量名记录名值列表举例DA1REC10AH,3,25H,6DA2REC21,8,0,1DA3REC35DUP(3,7,6,2)DA4REC43,3,0DA5REC4,3DA6REC410DUP()记录的运算符宽度运算符–WIDTH记录名或记录的字段名MOVAL,WIDTHF3MOVAL,WIDTHREC1移位值运算–记录字段名作为操作数,表示该字段处于记录中的位置(0-15)MOVBL,F1记录屏蔽运算–MASK记录的字段名–将所在记录的相应字段的各位设置为1,其他为0MOVAX,MASKF1对记录和字段的操作(1/2)对记录变量的操作MOVAX,DA1MOVBL,DA2MOVDA3+4,CX作为常数的记录操作数MOVAX,REC10BH,2,3AH,7MOVCL,REC4,0,0对记录和字段的操作(2/2)对记录字段的操作–例1:提取字段1MOVAX,DA1MOVCL,F1SHRAX,CL–例2:提取字段2MOVAX,DA1ANDAX,MASKF2MOVCL,F2SHRAX,CL宏概念宏定义宏调用举例宏的引入例如:经常需要显示单个字符movah,2movdl,'c'int21h–若使用过程实现,太短了开销过大若定义了OUTPUT宏,则使用OUTPUT'c‘–好处:代码简洁清晰、减少重复代码宏的概念宏使用过程:定义、调用和展开–宏指的是具有命名的汇编语言语句的指令块,一次定义,可以被多次调用。–在汇编器预处理的过程中,将各个宏展开拷贝到程序中。–展开后的代码在汇编过程中处理。宏定义•定义格式•无参数和有参数macronameMACRO[parameter-1,parameter-2,...]statement-listENDM例1:INPUT宏INPUTMACROMOVAH,01HINT21HANDAL,0FHENDM定义:.codeINPUT调用:从键盘输入0~9数字,保存在AL中例2:OUTPUT宏OUTPUTMACROcharPUSHAXMOVAL,charMOVAH,02HINT21HPOPAXENDM定义:.codeOUTPUT'A'调用:从屏幕输出一个字符例3:显示字符串的宏,需要保存寄存器displaymacrostringpushaxpushdxmovah,9movdx,offsetstringint21hpopdxpopaxendmmsg1db“beginoftest”,0Dh,0Ah,’$’msg2db“endoftest”,0Dh,0Ah,’$’调用displaymsg1displaymsg2宏调用(1of2)当调用宏时,各个实参和形参要对应当宏展开时,各个形参以对应的实参替换当宏展开时,产生汇编语言的源代码举例:–P170,其中+为展开部分宏调用(2of2)parametermacrotextargumentreplacesdeclaredinsideconsistsofpassesmacroinvocationstatementgeneratesassemblycode宏、形参和实参的关系:&与&–当实参需要和其它的字符连接起来,需要&连接起来。–当一个实参包含空格,逗号等时,用包装起来作为整体传递替换LOCAL为了防止宏中所使用的标号或变量名和程序中定义的其它标识符冲突,解决的方法:–在宏的开始,利用LOCAL声明所用的局部标识符–举例:p172宏库把一些常用的宏集中在相应的文件中,称为库文件使用时,只需在开始处利用INCLUDE包含库文件进来即可。–例:p174重复汇编REPT伪指令IRP伪指令IRPC伪指令REPT伪指令REPT伪指令重复执行指定次数的语句块语法:REPTconstExpressionstatementsENDMConstExpression为无符号整数表达式,决定了重复的次数例1例1:X=0REPT10;;generatedb1throughdb10X=X+1DBXENDM例2iVal=0REPT100DWiValiVal=iVal+10ENDM以下的代码产生100个DW数据序列:10,20,30,...不定重复重复的次数由实参的个数决定,每次循环时以相应的实参代替形参IRP形参,实参1,实参2,…statementsENDM例例1NUM=5IRPM,1,2,3DBNUM*MENDM例2PUSHREGMACROIRPREG,AX,BX,CXPUSHREGENDMENDM不定重复字符重复的次数由string的字符个数决定,每次循环时以相应的字符依次代替形参IRPC形参,stringstatementsENDM例例1:IRPCCHR,ABCDEFHDB‘&CHR&’ENDM例2:POPREGMACROIRPCREG,CBAPOPREG&XENDMENDM条件汇编IF/IFE,ELSE,和ENDIFIF,ELSE,和ENDIF伪指令IFboolean-expressionstatements[ELSEstatements]ENDIFIF若布尔表达式不为0时,相应的语句块被汇编;否则,汇编其它的语句块。IFE若布尔表达式为0时,则汇编举例:p176例:WriteStrinWriteStrMACROstringIFBstringECHO-----------------------------------------ECHO*Error:parametermissinginmWriteStrECHO*(nocodegenerated)ECHO-----------------------------------------EXITMENDIFPUSHDXMOVDX,OFFSETstringCALLWriteStringPOPDXENDM若string参数为空,汇编时显示消息:TheEnd