Intel汇编语言程序设计第五版Chapter10结构和宏课件_第1页
Intel汇编语言程序设计第五版Chapter10结构和宏课件_第2页
Intel汇编语言程序设计第五版Chapter10结构和宏课件_第3页
Intel汇编语言程序设计第五版Chapter10结构和宏课件_第4页
Intel汇编语言程序设计第五版Chapter10结构和宏课件_第5页
已阅读5页,还剩59页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

10.3条件汇编伪指令条件汇编伪指令的一般格式:

IFconditionstatements[ELSEstatements]ENDIF

当condition为真时,允许汇编statements中的语句。

10.3条件汇编伪指令条件汇编伪指令的一般格式:条件汇编伪指令伪指令说明IF表达式如果表达式为真则允许汇编。IFB<参数>如果参数为空则允许汇编,参数名必须用<>括起来IFNB<参数>如果参数不为空则允许汇编,参数名必须用<>括起来IFIDN<参数1>,<参数2>如果两个参数相同则允许汇编,参数区分大小写IFIDNI<参数1>,<参数2>如果两个参数相同则允许汇编,参数不区分大小写IFDIF<参数1>,<参数2>如果两个参数不同则允许汇编,参数区分大小写IFDIFI<参数1>,<参数2>如果两个参数不同则允许汇编,参数比区分大小写IFDEF名字如果名字已经定义则允许汇编IFNDEF名字如果名字未定义则允许汇编ENDIF结束一个条件汇编伪指令开始的语句块ELSE如果前面的条件均为假,则汇编该伪指令至ENDIF之间的语句EXITM立即退出宏,阻止其后任何语句的展开条件汇编伪指令伪指令说明IF表达式如果表达式为真则允许汇编检查缺少的参数mWriteStrMACROstring

IFB<string>ECHO--------------------------------------------------ECHO*Error:parametermissinginmWriteStrECHO*(nocodegenerated)ECHO--------------------------------------------------

EXITM

ENDIFpushedxmovedx,OFFSETstringcallWriteStringpopedxENDM

检查缺少的参数mWriteStrMACROstring默认的参数初始化值定义宏时可以有默认的参数初始化值,如果调用宏时未给出参数,则编译器使用默认参数值。格式为:

paramname:=<argument>例如:为mWriteLn宏提供一个空格作为默认的参数:

mWriteLnMACROtext:=<“”>mWritetextcallCrlfENDM如果调用时不带参数,那么仍然会打印一个空格并在后面跟一个换行符。默认的参数初始化值定义宏时可以有默认的参数初始化值,如果调用布尔表达式编译器允许在常量布尔表达式中使用以下关系运算符:

LT小于

GT大于

EQ等于

NE不等于

LE小于等于

GE大于等于布尔表达式编译器允许在常量布尔表达式中使用以下关系运算符:IF,ELSE和ENDIF伪指令格式为:

IFexpression

statement-list ENDIF或:

IFexpressionstatement-listELSEstatement-listENDIFIF伪指令后面必须跟一个常量布尔表达式。表达式可以包含常量、符号常量或宏参数常量,但不能是寄存器或变量名。

IF,ELSE和ENDIF伪指令格式为:例子:mGotoxyConst宏

mGotoxyConst宏使用LT和GT操作符对传递给宏的参数进行范围检查,参数X和Y必须是常量。另一个常量ERRS用于统计发现的错误数。例子:mGotoxyConst宏IFIDN和IFIDNI伪指令IFIDN伪指令以区分大小写的方式比较两个符号(包括宏参数)是否相等,如果相等则返回TRUE。IFIDNI伪指令则不区分大小写。格式为:

IFIDN<symbol>,<symbol>statementsENDIFIFIDN和IFIDNI伪指令IFIDN伪指令以区分大小写的mReadBufMACRObufferPtr,maxcharsIFIDNI<maxchars>,<EDX>ECHOWarning:secondargumenttomreadbufcannotbeedxECHO*******************************************EXITMENDIFpushecxpushedxmovedx,bufferPtrmovecx,maxcharscallReadStringpopedxpopecxENDM下面的语句将导致宏产生一条错误信息:

mReadBufOFFSETbuffer,edx

例如:下面的mReadBuf宏中,第二个参数不能是EDX,因为buffer的偏移被送到EDX时,参数会被覆盖。mReadBufMACRObufferPtr,ma例子:对矩阵行求和定义宏mCalc_row_summCalc_row_sumMACROindex,arrayOffset,rowSize,eltTypeLOCALL1……moveax,indexmovebx,arrayOffsetmovecx,rowSizemulecxaddebx,eaxshrecx,(TYPEeltType/2)moveax,0movesi,0L1:IFIDNI<eltType>,<DWORD>movedx,eltTypeptr[ebx+esi*(TYPEeltType)]ELSEmovzxedx,eltTypeptr[ebx+esi*(TYPEeltType)]ENDIF……loopL1ENDM例子:对矩阵行求和定义宏mCalc_row_sum特殊操作符&替换操作符<>文本操作符!特殊字符操作符%展开操作符特殊操作符&替换操作符<>文本操作符!特殊字符操作符%展开操替换操作符&

将宏的内部对宏参数的引用替换为调用时的实际值。ShowRegisterMACROregNameLOCALtempStr.datatempStrBYTE“®Name=”,0.codepusheaxpushedx

movedx,offsettempStrcallWriteString

moveax,regNamecallWriteHexpopedxpopeaxENDM当程序中出现宏调用语句:ShowRegisterECX则宏调用的输出为:

ECX=00000101替换操作符&将宏的内部对宏参数的引用替换为调用当程序中出现展开操作符%

展开文本宏并把常量表达式转换成文本。在与用TEXTEQU联合使用时,%操作符对常量表达式求值并将结果转化成整数。例1:count=10sumValTEXTEQU%(5+count);=“15”例2:mGotoxyConst%(5*10),%(3+4)

调用宏时,两个表达式分别被求值并作为参数传递展开操作符%展开文本宏并把常量表达式转换成文本。行首的%

当%作为源代码行的第一个字符时,预处理器将展开在该行发现的所有文本宏和宏函数。例子:

.dataarrayDWORD1,2,3,4,5,6,7,8TempStrTEXTEQU%(SIZEOFarray).code%ECHOThearraycontainsTempStrbytes

产生的输出为:

Thearraycontains32bytes行首的%当%作为源代码行的第一个字符时,预处理器将展开文本操作符<>

将多个字符或符号作为一个字符串进行传递。

例如,本章前面的宏只接收一个唯一的字符串参数,如果传递以下字符串,预处理器将解释为三个参数:

mWrite“Linethree”,0dh,0ah如果用文本操作符将字符串括起来,预处理器会将文本操作符里面的所有字符都作为单个宏参数进行传递:

mWrite<“Linethree”,0dh,0ah>文本操作符<>将多个字符或符号作为一个字符串进行传递。特殊字符操作符!强制预处理器将预定义的操作符作为原始字符进行传递。

例如:

BadYValueTEXTEQU<Warning:Y=coordinateis!>24>特殊字符操作符!强制预处理器将预定义的操作符作为原始字符进操作符的结合使用BadYValueTEXTEQU<Warning:Y-coordinateis!>24>ShowWarningMACROmessagemWrite“&message”ENDM则以下的宏调用:

.codeShowWarning%BadYValue将产生如下结果:Warning:Y-coordinateis>24先替换后展开操作符的结合使用BadYValueTEXTEQU<War宏函数与宏过程类似,宏函数也是一个命名的汇编语句块,唯一的不同在于,宏函数总是用EXITM伪指令返回一个常量值(整数或字符串)。例如:IsDefinedMACROsymbolIFDEFsymbolEXITM<-1>;;TrueELSEEXITM<0>;;FalseENDIFENDM宏函数与宏过程类似,宏函数也是一个命名的汇编语句块,唯一的不调用宏函数:调用宏函数时参数列表必须用圆括号括起来。

例如:调用IsDefined宏,并向它传递一个已经或尚未定义的参数RealMode:

IFIsDefined(RealMode)movax,@datamovds,axENDIF

如果编译器在编译该语句之前已经遇到了RealMode的定义,则编译后面两条语句。调用宏函数:调用宏函数时参数列表必须用圆括号括起来。10.4定义重复块

WHILE伪指令

REPEAT伪指令

FOR伪指令

FORC伪指令

链表10.4定义重复块WHILE伪指令MASM中的重复块伪指令只能用于编译期间,而且只能使用常量值作为循环条件和计数器。WHILE伪指令根据一个布尔表达式来重复语句块REPEAT伪指令根据一个计数器来重复语句块FOR伪指令通过遍历一个符号列表中的每个符号来重复语句块FORC伪指令通过遍历一个字符串中的每个字符来重复语句块MASM中的重复块伪指令只能用于编译期间,而且只能使用常量值WHILE伪指令格式如下:WHILEconstExpressionstatementsENDM只要常量表达式constExpression的值为真,WHILE伪指令就重复语句块。例如:以下代码显示了如何生成1到F0000000h之间的斐波那契数作为一系列编译时期的常量。WHILE伪指令格式如下:.dataval1=1val2=1DWORDval1DWORDval2val3=val1+val2WHILEval3LT0F0000000hDWORDval3val1=val2val2=val3val3=val1+val2ENDM.dataREPEAT伪指令REPEAT伪指令以固定次数重复指令块。格式为:

REPEATconstExpressionstatementsENDMconstExpression是一个无符号整数常量表达式,它决定了重复次数。REPEAT伪指令REPEAT伪指令以固定次数重复指令块。格例如:以下的REPEAT循环创建了包含100个双字的数组并用数列{10,20,30,40,……,1000}对其进行初始化:

ival=10REPEAT100DWORDivalival=ival+10ENDM例如:以下的REPEAT循环创建了包含100个双字的数组并用FOR伪指令FOR伪指令通过遍历一个以逗号分隔的符号列表重复语句块,符号列表中的每个符号都引发一次循环。格式如下:

FORparameter,<arg1,arg2,arg3,…>statementsENDM

第i次循环时,参数parameter被赋值为argiFOR伪指令FOR伪指令通过遍历一个以逗号分隔的符号列表重复FORC伪指令FORC伪指令通过遍历一个字符串中的每个字符来重复语句块,字符串中的每个字符都引发一次循环。格式如下:

FORCparameter,<string>statementsENDM

第i次循环中,参数parameter等于字符串string中的第i个字符。FORC伪指令FORC伪指令通过遍历一个字符串中的每个字符来例如:

DelimitersLABELBYTEFORcode,<@#$%^&*!<!>>BYTE“&code”ENDM将生成以下数据:00000000401BYTE“@”00000001231BYTE“#”00000002241BYTE“$”00000003251BYTE“%”000000045E1BYTE“^”00000005261BYTE“&”000000062A1BYTE“*”000000073C1BYTE“<”000000083E1BYTE“>”例如:链表每个节点的数据区内可以使用一个或多个变量存放节点的数据。在链接区中,用一个指针包含和链表相邻的下一节点的地址。最后一个节点的链接区通常包含一个空指针。datalinddatalinddatalindNULL链表每个节点的数据区内可以使用一个或多个变量存放节点的数据。例子:首先创建一个链表节点类型,该类型包含一个整数(数据区)和一个指向下一个相邻节点的指针(链接区):

ListNodeSTRUCTNodeDataDWORD?NextPtrDWORD?ListNodeENDS例子:首先创建一个链表节点类型,该类型包含一个整数(数据区)接着使用REPEAT伪指令创建ListNode对象的多个实例:TotalNodeCount=15NULL=0Counter=0.dataLinkedListLABELDWORDREPEATTotalNodeCountCounter=Counter+1ListNode<Counter,($+Counter*SIZEOFListNode)>ENDMListNode<0,0>$总是返回第一个节点的地址接着使用REPEAT伪指令创建ListNode对象的多个实例对于链表中节点的遍历,往往采用间接操作数,并结合PTR操作符进行:如:

(ListNodePTR[esi]).NodeData(ListNodePTR[esi]).NextPtr程序清单:P318对于链表中节点的遍历,往往采用间接操作数,并结合PTR操作符10.3条件汇编伪指令条件汇编伪指令的一般格式:

IFconditionstatements[ELSEstatements]ENDIF

当condition为真时,允许汇编statements中的语句。

10.3条件汇编伪指令条件汇编伪指令的一般格式:条件汇编伪指令伪指令说明IF表达式如果表达式为真则允许汇编。IFB<参数>如果参数为空则允许汇编,参数名必须用<>括起来IFNB<参数>如果参数不为空则允许汇编,参数名必须用<>括起来IFIDN<参数1>,<参数2>如果两个参数相同则允许汇编,参数区分大小写IFIDNI<参数1>,<参数2>如果两个参数相同则允许汇编,参数不区分大小写IFDIF<参数1>,<参数2>如果两个参数不同则允许汇编,参数区分大小写IFDIFI<参数1>,<参数2>如果两个参数不同则允许汇编,参数比区分大小写IFDEF名字如果名字已经定义则允许汇编IFNDEF名字如果名字未定义则允许汇编ENDIF结束一个条件汇编伪指令开始的语句块ELSE如果前面的条件均为假,则汇编该伪指令至ENDIF之间的语句EXITM立即退出宏,阻止其后任何语句的展开条件汇编伪指令伪指令说明IF表达式如果表达式为真则允许汇编检查缺少的参数mWriteStrMACROstring

IFB<string>ECHO--------------------------------------------------ECHO*Error:parametermissinginmWriteStrECHO*(nocodegenerated)ECHO--------------------------------------------------

EXITM

ENDIFpushedxmovedx,OFFSETstringcallWriteStringpopedxENDM

检查缺少的参数mWriteStrMACROstring默认的参数初始化值定义宏时可以有默认的参数初始化值,如果调用宏时未给出参数,则编译器使用默认参数值。格式为:

paramname:=<argument>例如:为mWriteLn宏提供一个空格作为默认的参数:

mWriteLnMACROtext:=<“”>mWritetextcallCrlfENDM如果调用时不带参数,那么仍然会打印一个空格并在后面跟一个换行符。默认的参数初始化值定义宏时可以有默认的参数初始化值,如果调用布尔表达式编译器允许在常量布尔表达式中使用以下关系运算符:

LT小于

GT大于

EQ等于

NE不等于

LE小于等于

GE大于等于布尔表达式编译器允许在常量布尔表达式中使用以下关系运算符:IF,ELSE和ENDIF伪指令格式为:

IFexpression

statement-list ENDIF或:

IFexpressionstatement-listELSEstatement-listENDIFIF伪指令后面必须跟一个常量布尔表达式。表达式可以包含常量、符号常量或宏参数常量,但不能是寄存器或变量名。

IF,ELSE和ENDIF伪指令格式为:例子:mGotoxyConst宏

mGotoxyConst宏使用LT和GT操作符对传递给宏的参数进行范围检查,参数X和Y必须是常量。另一个常量ERRS用于统计发现的错误数。例子:mGotoxyConst宏IFIDN和IFIDNI伪指令IFIDN伪指令以区分大小写的方式比较两个符号(包括宏参数)是否相等,如果相等则返回TRUE。IFIDNI伪指令则不区分大小写。格式为:

IFIDN<symbol>,<symbol>statementsENDIFIFIDN和IFIDNI伪指令IFIDN伪指令以区分大小写的mReadBufMACRObufferPtr,maxcharsIFIDNI<maxchars>,<EDX>ECHOWarning:secondargumenttomreadbufcannotbeedxECHO*******************************************EXITMENDIFpushecxpushedxmovedx,bufferPtrmovecx,maxcharscallReadStringpopedxpopecxENDM下面的语句将导致宏产生一条错误信息:

mReadBufOFFSETbuffer,edx

例如:下面的mReadBuf宏中,第二个参数不能是EDX,因为buffer的偏移被送到EDX时,参数会被覆盖。mReadBufMACRObufferPtr,ma例子:对矩阵行求和定义宏mCalc_row_summCalc_row_sumMACROindex,arrayOffset,rowSize,eltTypeLOCALL1……moveax,indexmovebx,arrayOffsetmovecx,rowSizemulecxaddebx,eaxshrecx,(TYPEeltType/2)moveax,0movesi,0L1:IFIDNI<eltType>,<DWORD>movedx,eltTypeptr[ebx+esi*(TYPEeltType)]ELSEmovzxedx,eltTypeptr[ebx+esi*(TYPEeltType)]ENDIF……loopL1ENDM例子:对矩阵行求和定义宏mCalc_row_sum特殊操作符&替换操作符<>文本操作符!特殊字符操作符%展开操作符特殊操作符&替换操作符<>文本操作符!特殊字符操作符%展开操替换操作符&

将宏的内部对宏参数的引用替换为调用时的实际值。ShowRegisterMACROregNameLOCALtempStr.datatempStrBYTE“®Name=”,0.codepusheaxpushedx

movedx,offsettempStrcallWriteString

moveax,regNamecallWriteHexpopedxpopeaxENDM当程序中出现宏调用语句:ShowRegisterECX则宏调用的输出为:

ECX=00000101替换操作符&将宏的内部对宏参数的引用替换为调用当程序中出现展开操作符%

展开文本宏并把常量表达式转换成文本。在与用TEXTEQU联合使用时,%操作符对常量表达式求值并将结果转化成整数。例1:count=10sumValTEXTEQU%(5+count);=“15”例2:mGotoxyConst%(5*10),%(3+4)

调用宏时,两个表达式分别被求值并作为参数传递展开操作符%展开文本宏并把常量表达式转换成文本。行首的%

当%作为源代码行的第一个字符时,预处理器将展开在该行发现的所有文本宏和宏函数。例子:

.dataarrayDWORD1,2,3,4,5,6,7,8TempStrTEXTEQU%(SIZEOFarray).code%ECHOThearraycontainsTempStrbytes

产生的输出为:

Thearraycontains32bytes行首的%当%作为源代码行的第一个字符时,预处理器将展开文本操作符<>

将多个字符或符号作为一个字符串进行传递。

例如,本章前面的宏只接收一个唯一的字符串参数,如果传递以下字符串,预处理器将解释为三个参数:

mWrite“Linethree”,0dh,0ah如果用文本操作符将字符串括起来,预处理器会将文本操作符里面的所有字符都作为单个宏参数进行传递:

mWrite<“Linethree”,0dh,0ah>文本操作符<>将多个字符或符号作为一个字符串进行传递。特殊字符操作符!强制预处理器将预定义的操作符作为原始字符进行传递。

例如:

BadYValueTEXTEQU<Warning:Y=coordinateis!>24>特殊字符操作符!强制预处理器将预定义的操作符作为原始字符进操作符的结合使用BadYValueTEXTEQU<Warning:Y-coordinateis!>24>ShowWarningMACROmessagemWrite“&message”ENDM则以下的宏调用:

.codeShowWarning%BadYValue将产生如下结果:Warning:Y-coordinateis>24先替换后展开操作符的结合使用BadYValueTEXTEQU<War宏函数与宏过程类似,宏函数也是一个命名的汇编语句块,唯一的不同在于,宏函数总是用EXITM伪指令返回一个常量值(整数或字符串)。例如:IsDefinedMACROsymbolIFDEFsymbolEXITM<-1>;;TrueELSEEXITM<0>;;FalseENDIFENDM宏函数与宏过程类似,宏函数也是一个命名的汇编语句块,唯一的不调用宏函数:调用宏函数时参数列表必须用圆括号括起来。

例如:调用IsDefined宏,并向它传递一个已经或尚未定义的参数RealMode:

IFIsDefined(RealMode)movax,@datamovds,axENDIF

如果编译器在编译该语句之前已经遇到了RealMode的定义,则编译后面两条语句。调用宏函数:调用宏函数时参数列表必须用圆括号括起来。10.4定义重复块

WHILE伪指令

REPEAT伪指令

FOR伪指令

FORC伪指令

链表10.4定义重复块WHILE伪指令MASM中的重复块伪指令只能用于编译期间,而且只能使用常量值作为循环条件和计数器。WHILE伪指令根据一个布尔表达式来重复语句块REPEAT伪指令根据一个计数器来重复语句块FOR伪指令通过遍历一个符号列表中的每个符号来重复语句块FORC伪指令通过遍历一个字符串中的每个字符来重复语句块MASM中的重复块伪指令只能用于编译期间,而且只能使用常量值WHILE伪指令格式如下:WHILEconstExpressionstatementsENDM只要常量表达式constExpression的值为真,WHILE伪指令就重复语句块。例如:以下代码显示了如何生成1到F0000000h之间的斐波那契数作为一系列编译时期的常量。WHILE伪指令格式如下:.dataval1=1val2=1DWORDval1DWORDval2val3=val1+val2WHILEval3LT0F0000000hDWORDval3val1=val2val2=val3val3=val1+val2ENDM.dataREPEAT伪指令REPEAT伪指令以固定次数重复指令块。格式为:

REPEATconstExpressionstatementsENDMconstExpression是一个无符号整数常量表达式,它决定了重复次数。REPEAT伪指令REPEAT伪指令以固定次数重复指令块。格例如:以下的REPEAT循环创建了包含100个双字的数组并用数列{10,20,30,40,……,1000}对其进行初始化:

ival=10REPEAT100DWORDivalival=ival+10ENDM例如:以下的REPEAT循环

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论