汇编语言程序设计08结构和宏以及课程总结.ppt
汇编语言程序设计,_08_结构和宏以及课程总结大连理工大学软件学院_朱明2009年5月31日_ V1.1,Section 1,结构,结构Structure是逻辑上相互关联的一组变量的模板,结构中的单个变量称为域 结构将一类数据进行了归集,进程间传递参数方便 将相关的数据存放在一个结构中 向过程传递该结构的地址 结构可以减少堆栈空间的使用 结构的使用过程 定义结构 声明一个或多个该结构的变量(结构变量)运行时访问结构或结构中的域 定义结构时要特别注意对齐的问题,汇编语言程序设计-朱明,2,结构,结构的定义 域的初始化与普通变量和数组的初始化基本相同,汇编语言程序设计-朱明,3,结构名STRUCT域的声明结构名ENDS,COORD STRUCT X WORD?Y WORD?COORD ENDS,EmployeeSTRUCTIDNumBYTE“000000000”LastNameBYTE 30 DUP(0)YearsWORD 0SalHistoryDWORD 0,0,0,0EmployeeENDS,“000000000”IDName,(null)LastName,0years,0 0 0 0SalHistory,Section 1,结构,结构变量的声明 结构变量的声明的基本格式 通过尖括号实现对结构变量的声明,尖括号中的内容表示从左向右顺序定义的结构变量对应位置的域的值,左边不需要重性赋值的域可以直接通过逗号忽略,汇编语言程序设计-朱明,4,COORD STRUCT X WORD?Y WORD?COORD ENDS,Point1COORD Point2 COORD Point3COORD Point4COORD,结构体变量名结构体名,Person1 EmployeePerson2 Employee,Section 1,结构,结构的尺寸与尺寸操作符,汇编语言程序设计-朱明,5,EmployeeSTRUCTIDNumBYTE“000000000”;+9BLastNameBYTE 30 DUP(0);+30ALIGNWORD;+1BYearsWORD 0;+2ALIGNDWORD;+2BSalHistoryDWORD 0,0,0,0;+16EmployeeENDS;=60,Section 1,WorkerEmployee,TYPEEmployee;60,SIZEOFEmployee;60,SIZEOFWorker;60,TYPE取标识符的存储类型,SIZEOF取标识符的存储尺寸,结构,结构中域的尺寸与访问 使用结构或者结构变量名作为修饰访问域 间接寻址和变址寻址访问结构 MASM规定间接寻址访问结构时必须使用PTR操作符 workeresi.Year访问的是哪里?,汇编语言程序设计-朱明,6,TYPEEmployee.SalHistory;4,movdx,Worker.Yearsmovworker.SalHistory,20000;第一个值movwork.SalHistory+4,3000;第二个值,workerEmployee5 DUP()movesi,OFFSET workermovax,(Employee PTR esi).Yearmovesi,TYPE Employeemovworkeresi.Year,4,Section 1,结构的练习,系统的时间问题 Windows系统会给我们什么样的时间 年、月、日、小时、分钟、秒、星期、毫秒 GetLocalTime过程,并传递对应结构变量的地址,汇编语言程序设计-朱明,7,LOCALGetLocalTime,ADDR sysTime,SYSTEMTIMESTRUCTwYearWORD?wMonthWORD?wDayOfWeekWORD?wDayWORD?wHourWORD?wMinuteWORD?wSecondWORD?wMilliSecondsWORD?SYSTEMTIMEENDS,Section 1,结构的嵌套,结构中可以包含其他结构实例,汇编语言程序设计-朱明,8,COORD STRUCT X WORD?Y WORD?COORD ENDS,Rectangle STRUCT UpperLeft COORD LowerRightCOORD Rectangle ENDS,rect1Rectanglerect2Rectangle,movrect1.LowerRight.X,15,Section 1,movesi,OFFSET rect1mov(Rectangle PTR esi).UpperLeft.Y,25,movesi,OFFSET rect1mov(Rectangle PTR esi).UpperLeft.Y,25,联合,结构与联合 结构的每一个域都有一个相对于结构的首地址的偏移,结构的大小等于所有域的大小的和 联合中所有的于都从同一个偏移地址开始,联合的大小是联合中最大的元素的长度,汇编语言程序设计-朱明,9,Section 2,域1,域2,域3,域4,域1,域2,域3,域4,联合名STRUCT域的声明联合名ENDS,Integer UNION D DWORD 0 W WORD 0 B BYTE 0Integer ENDS,联合,联合变量的声明与初始化与结构变量大致相同 联合只允许一个初始值的初始化 联合与结构联合使用时,应注意各自的特性 联合中可以包含结构,结构中也可以包含联合,汇编语言程序设计-朱明,10,Section 2,Integer UNION D DWORD 0 W WORD 0 B BYTE 0Integer ENDS,Val1IntegerVal2IntegerVal3Integer,movval3.B,almovval3.W,axmovval3.D,eax,课堂练习,创建一个包含有两个域的结构MyStruct:field1域是一个字,field2是20个双字的数组,不初始化值 声明一个MyStruct结构变量,使用默认值 声明一个MyStruct结构变量,第二个域的值全部为0 声明一个包含了20个MyStruct对象的数组 使用下面的Triangle结构声明一个结构变量并将其初始化为(0,0),(5,0)和(7,6),汇编语言程序设计-朱明,11,Section 2,Triangle STRUCT Vertex1 COORD Vertex2 COORD Vertex3 COORD Triangle ENDS,宏,宏(Macro Procedure)是一个命名的汇编语句块,一旦被定义后,宏就可以在程序中被调用任意多次 调用宏过程的时候,宏内的汇编语句块的一份副本会被插入到程序中调用宏过程的地方 宏过程:MASM中对没有返回值的宏的称呼 宏函数:MASM中对有返回值的宏的称呼 定义但是没有被调用的宏会被汇编器忽略 宏的最基本的功能就是代码的替换 宏的处理是在预处理阶段完成的 宏的功能不仅仅是简单的替换,汇编语言程序设计-朱明,12,Section 3,宏,宏的定义 宏的参数可以用来传递调用者传递给宏的文本参数 可以是整数、变量名或者其他值 对于宏的参数的检查是在预处理之后由汇编器检查的,汇编语言程序设计-朱明,13,Section 3,宏名MACRO 参数1,参数2,内容列表ENDM,mPutCharMACROcharpusheaxmoval,charcallWriteCharpopeaxENDM,宏,宏的调用 宏的实际参数必须与宏定义的参数顺序相同 预处理器会将上面的宏调用自动展开成代码(宏里面的注释也会被一并展开,不展开注释可以使用双分号),汇编语言程序设计-朱明,14,Section 3,宏名参数1,参数2,,mPutCharMACROcharpusheaxmoval,charcallWriteCharpopeaxENDM,mPutCharA,宏,其他与宏有关的内容 通过REQ来修饰宏的参数,以表示该参数是必须的 如果在宏内部定义了变量,并多次调用该宏,在宏展开之后,就会产生相同名称变量的重复定义问题,可以通过LOCAL伪指令修饰变量以解决这个问题,汇编语言程序设计-朱明,15,mPutCharMACROchar:REQ,makeStringMACROtextLOCALString.dataStringBYTE“0”ENDM,Section 3,条件汇编伪指令,区分条件汇编伪指令和决策伪指令 IF/ELSEIF/ELSE/EDNIF,控制汇编,即是否允许汇编.IF/.ELSEIF/.ELSE/.ENDIF,控制运行流程的 条件汇编伪指令的种类 IF 表达式:如果表达式为真则允许汇编 IFB:如果参数为空则允许汇编 IFNB:如果参数不为空则允许汇编 IFDEF 名字:如果名字已经定义则允许汇编 IFNDEF 名字:如果名字未定义则允许汇编 ENDIF:结束条件汇编伪指令块 EXITM:强行立刻退出当前宏,汇编语言程序设计-朱明,16,Section 3,IF条件内容ELSE内容ENDIF,条件汇编伪指令,IF条件汇编伪指令的表达式 LT、GT、EQ、NE、LE、GE,汇编语言程序设计-朱明,17,Section 3,mGotoCOnstMACRO X:REQ,Y:REQIF(X LT 0)OR(X GT)79ECHO Warning X.movERRS,1ENDIFIF(Y LT 0)OR(Y GT 24)ECHO Warning YmovERRS,1ENDIFIF ERRS GT 0EXITMEMDM,特殊操作符,MASM汇编语言系统中同样有很多的特殊操作符$:前一章在介绍二维数组时使用到,当前地址 更适合用于宏的汇编操作符&:替换操作符:文本操作符!:特殊字符操作符%:展开操作符,汇编语言程序设计-朱明,18,tableBYTE 10h,20h,30h,40h,50hRowsize=($-table)BYTE 60h,70h,80h,90h,0A0hBYTE 0B0h,0C0h,0D0h,0E0h,0F0h,Section 4,特殊操作符,替换操作符:&将宏内部对宏参数的引用替换成为调用时的实际值 irvine32提供的mShowRegister宏的功能处理器会认为regName是字符串的一部份 该宏中使用&操作符,因此预处理器会在字符串的地方强制插入实际传递的宏参数(例如ECX),汇编语言程序设计-朱明,19,Section 4,mShowRegister ECX,ECX=00000101,mShowRegisterMACROregName.datatempStr BYTE“®Name=”,0,mShowRegisterMACROregName.datatempStr BYTE“®Name=”,0,特殊操作符,文本操作符:将多个字符或者符号作为一个字符串整体传递,以防止预编译器单独解释 特殊文本字符操作符:!特殊文本字符操作符同样用于强制预处理器把预定义的操作符字符作为普通的字符处理,汇编语言程序设计-朱明,20,mWrite,BadYValue TEXTEQU 24,BadYValue TEXTEQU 24,Section 4,特殊操作符,展开操作符:%展开操作符用于将文本宏或者常量表达式转换为文本 需要特别注意的是,也只有当展开操作符作为源码行的第一个字符的时候,才会指示预处理器展开所有的文本宏和宏函数 上面的函数不会展开sizeof array的内容,汇编语言程序设计-朱明,21,Count=10SumVal TEXTEQU%(5+count);=“15”,ECHOThe array contains%(sizeof array)bytes,Section 4,TempStrTEXTEQU%(sizeof array)%ECHOThe array contains TempStr bytes,宏函数,宏函数:总是通过EXITM返回一个常量 IsDefine:如果一个符号已经定义,则返回-1,否则则返回0 调用IsDefine,判断一个符号是否定义,汇编语言程序设计-朱明,22,IsDefine MACRO symbol IFDEF symbol EXITM ELSE EXITM ENDIFENDM,IFIsDefine(ChunGe)movax,1movds,alENDIF,Section 4,看看我们前面的课程,_01_课程介绍与IA-32处理器结构 _02_数据表示与汇编语言基础 _03_简单的算术运算与数据传送 _04_循环控制与过程 _05_IRVINE链接库与条件处理 _06_整数运算指令与高级过程 _07_高级过程与字符串和数组 _08_结构和宏以及课程总结,汇编语言程序设计-朱明,23,回首来时路,END,汇编语言程序设计-朱明,24,不积跬步无以至千里不积小流无以成江海,回首来时路,时光荏苒,转眼间我们已经共同走过了小学期的四周时间。四周时间里面的每一节课都是我快乐的进步,谢谢大家!我们的学习就像是人生,我们都是从爬行走向奔跑、从幼稚走向成熟、从无知走向博学,在人生的道路上我们会遇到艰难和险阻,在学习的路上我们也会遇上各种疑问与困惑。面对艰险、面对疑惑,只要大家脚踏实地、勤奋求实,这些问题就都不应该、也不可能成为我们进步的障碍。祝愿大家都有一个美好的明天!,