⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 宏.txt

📁 会变语言实现的一些程序
💻 TXT
📖 第 1 页 / 共 2 页
字号:
FOR reg, 
  xor reg, reg
ENDM
  ENDM

不过要注意的是VARARG修饰的参数必须是参数中的最后一个。

让宏返回一个值
宏过程和宏函数的区别在于是否有返回值。当然这里的返回值和执行期的函数的返回值也是很不一样的。执行期的函数是通过eax来传递返回值的。而这里,也不过是直接替换而已。返回值的语法是这样的:

EXITM textitem

一个宏函数可以有多个EXITM,就像C中的函数可以有多个return一样。不过必须返回值一致。看一个简单的例子

  Who MACRO
EXITM 
  ENDM
  %echo Who()

结果是显示taowen。如果把()去掉,则显示的是who。可见对于宏函数的调用一定要加上 ()。而调用宏过程则不能加()。看一个有趣的例子:

  Who MACRO temp
%echo temp
  ENDM
  Who()

显示的结果是()。说明()被当作传递给宏过程的参数了。

可以比较随意的使用返回值,可以把返回值这么用。

  Who MACRO
EXITM 
  ENDM
  Who() TEXTEQU 

这样就定义了汇编期文本变量,值为genius。可见宏函数可以用在任何文本变量可以出现的地方,很多地方可以把高级语言中函数中那些类推过来。

局部变量
宏中可以有局部变量,它看起来像局部的,实际上不过是一些名称上的小技巧。

对于局部变量有两点事实:1、在函数外无法访问,2、在对函数的不同次的调用中其值应该不受前次调用的影响。

  TestMacro MACRO
  LOCAL LocalVar
%echo LocalVar
LocalVar TEXTEQU 
  ENDM

如果对于函数的调用每次之间会互相影响,那么这么调用:

  TestMacro
  TestMacro

第一次会产生一个未定义变量的错误,而第二次就会输出Hello。事实上,由于LocalVar 是LOCAL的。所以两次都是未定义错误。这个就体现了局部变量的多次调用的独立性。

下面我们来揭穿局部变量的底牌。不用我多叙述,直接看看这个你就明白了:

  TestMacro MACRO
  LOCAL LocalVar
echo LocalVar
  ENDM
  TestMacro
  TestMacro

输出的结果是:??0000与??0001。这个就是局部变量的实际名字。局部变量就是通过怪怪的名字让外部无法访问(你不知道它是什么名字),然后在每次展开同一个宏的时候用不同的名字替换局部变量的名字,使得多次调用之间不会互相影响。

其实你可以试验一下这个:

  ??0000 TEXTEQU 
  TestMacro MACRO
  LOCAL LocalVar
%echo LocalVar
  ENDM
  TestMacro

显示的结果是Hello,这样就在一个宏过程(函数)的外部访问了局部变量。

文本操作
MASM内置了两套文本操作功能,一个是宏函数,另一个是Directive。功能是一样的,但是提供了表达上的灵活性。

name CATSTR [[textitem1 [[, textitem2]] ...]]
name INSTR [[position,]] textitem1, textitem2
name SIZESTR textitem
name SUBSTR textitem, position [[, length]]

这一套是Directive,作用分别是:连接文本,查找子文本,获得文本长度,取子文本。 

@CatStr( string1 [[, string2...]] )
@InStr( [[position]], string1, string2 )
@SizeStr( string )
@SubStr( string, position [[, length]] )

这一套是宏函数。用一个例子显示两套其实是一样的:

taowen TEXTEQU @CatStr(, )
%echo taowen

taowen CATSTR , 
%echo taowen

可以看到两个例子输出的都是He is genius。有两点需要注意:1、@CatStr这样的宏函数可以作为左值,被用来赋值。2、@CatStr这样的宏函数对于参数并不自动求值,当行为和你想的不一样的时候,加上%。

对于具体的使用不是很难,试验一下就可以知道了。一点就是第一个字符的索引是1,而不是C中的0。

%与求值
%可能是最难使用的语法了。一般就是行为和你想的不一样的时候,加上%试验一下。%与 <>与!等,构成了一团糟。

一般情况下,你不用%号。用%可以把数值变量转变为文本变量。可以用%号强制取出文本的值。比如:

  Index = 0
  NameT CATSTR , %Index
  %NameT TEXTEQU 
  %echo Person0

先对Index用%就是把数值变成文本,第二个%就是把NameT变成Person0。这里也演示了一个产生变量名的很重要的技巧,只要把Index进行一些递增,就能够构建一个变量的数组了。 

<>可以一定程度上放置被求值,不过大部分情况下由于文本宏的替换不受影响,所以仍然取到的是替换后的值。!用来取消符号原有的意思。比如:

  Symbol CATSTR , , 
  %echo Symbol

输出的结果是Go, Go。如果不加!则,号会导致错误。有趣的是如果你在第二个Go后面加上 !本来应该是Go, Go!。结果确实一个缺少右尖括号的错误,原来是!把>的原有意思变化了,不再表示结束了。如果你这样:

  Symbol CATSTR , , >
  %echo Symbol

得出的就是Go, Go>。看出来是怎么回事了吧。要产生!,就这么写:

  Symbol CATSTR , , 
  %echo Symbol

关于什么时候用<>什么时候不用,我的看法是最好能用<>就用<>。具体为什么,是因为能够加大适用范围。

在宏中进行循环
循环有四种:WHILE,REPEAT,FOR,FORC。语法如下:

  WHILE expression
statements
  ENDM
  REPEAT expression
statements
  ENDM
  FOR parameter [[:REQ | :=default]] , 
statements
  ENDM
  FORC parameter, 
statements
  ENDM

WHILE与REPEAT从用法到效果是一样的,至少我认为是一样的。expression要求值为一个数值,可以用EQ(等于),LT(小于)这些判断Operator来比较数值。

  I = 0
  WHILE I LT 10
Temp TEXTEQU %I
%echo Temp
I = I + 1
  ENDM

输出的结果就是0一直到9。

FOR与FORC是专门用途的循环,一个是用于取得一个参数列表中的各个参数,另一个是逐个取出一个字符串中的每个字符。各举两个例子就可以明白:

  TestMacro MACRO params:VARARG
FOR param, 
  %echo param
ENDM
  ENDM
  TestMacro arg1, arg2, arg3

显示的结果是arg1然后是arg2然后是arg3。

  FORC char, 
%echo char
  ENDM

分别显示的是H和e和l和l和o。

在宏中进行判断
判断很简单了,不过有很多种IF,IFDEF,IFIDN,IFE,IFNDEF,IFDIF。使用上没有什么值得注意的都比较简单。分别是判断数值,判断符号是否定义,判断两个文本是否一致。

关于宏还有定义在宏中的宏,OPATTR, SIZEOF, LENGTHOF, 等等许多比较高级的东西。不过我相信有前面讲述的基础,这些东西的使用不过是查查手册的事情。

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -