这时你就可以用CTEXT宏
CTEXT MACRO y:VARARG ;This is a good macro LOCAL sym
CONST segment IFIDNI
这样你就可以用inoke LoadLibrary,CTEXT(\方便地使用了,尤其是代码比较长的时候不用翻来翻去 ,定义数据,然后再offset ****了...呵呵.
其他的下面的宏功能基本是一致的. dsText MACRO name,Text:VARARG .data
name db Text,0 .code ENDM
下面这个宏用于在代码段里面定义数据,在链接的时候注意假如/SECTION:.text,EWR否则读写这 类数据会产生非法操作.
szText MACRO name,Text:VARARG jmp @f name db Text,0 @@:
ENDM
你可以根据需要选用.
4)$invoke宏,用于inline Coding,在C里面你肯定看到过GetModuleFileName(GetModuleHandle(0),&buf);的语句在 asm里面依然可以实现...那就是用下面的$invoke宏: $invoke Macro fun:REQ,args:VARARG IFNB
不过要注意寄存器争用的情况,比如第3个参数用到eax,那么第一、二个参数就不能用这个内嵌宏 .
5)RGB和$RGB
在GDI编程里面经常遇到用RGB值作为参数的情况,为了简化这以过程可以定义下面的宏 RGB MACRO red,green,blue xor eax,eax mov ah,blue shl eax,8 mov ah,green mov al,red ENDM
然后在RGB宏后面用eax作为RGB值参数,这诗歌好想法,不过还不够好,因为占用了多余的代码行,
实际上我们需要的仅仅是一格RGB值,于是有了下面的宏: $RGB MACRO red:REQ, green:REQ, blue:REQ ;This is better... EXITM %(red + 256 * (green + (256 * blue))) ENDM
6)pushm和popm
这时为了简化寄存器的入栈和出栈而设计的,很简单: pushm Macro args:VARARG IFNB
.ERR
popm Macro args:VARARG IFNB
.ERR
7)数据定义rb,rw,rd,rq....
你喜欢这种方式吗?比如buf db 260 dup(?)是不是很烦琐用下面的宏就可以rb buf,260是不是更简单呢?这时我喜欢的.... rb Macro label:REQ,count
IFNB
label db &count dup(?) ELSE label db ? ENDIF EndM
类似的是rw,rd,rq...等具体参见我的文件.
8)revargs将参数反向排列(special thx to lyb)
在stdcall调用模式里面使用的是反向压入参数的调用约定,MASM的宏并没有提供反向参数的 机制,我们得字节写一个宏.
revargs MACRO args:VARARG LOCAL target target TEXTEQU <> count=0 FOR arg,
target CATSTR
IF count GT 0
target SUBSTR target,1,@SizeStr(%target)-1 EXITM target ENDIF ENDM
用于需要反向排列参数的地方.
9)iWin32,iWin32i,避免jmp tabel,有两种方法避免生成jmp tabel(thx to EliCZ's macro)
一种我以前写的一篇文章里面介绍过,就是利用声明 _imp__&Win32Api&A proto :DWORD,.... 然后
call dword ptr [_imp__&Win32Api&A]
格式另一种是ELiCZ的方法,就是声明
externdef _imp__&Win32Api&A@NUM:DWORD,其中NUM是参数个数 然后
call _imp__&Win32Api&A来调用.
由于用EliCZ的方法写的macro较长,下面根据我的方法写一个宏:
iWin32 Macro Win32API:REQ,args:VARARG LOCAL sz1 sz1 TEXTEQU <>
% FOR pxx,
sz1 CATSTR sz1,<,:DWORD> ENDIF ENDM
sz1 SUBSTR sz1,2,@SizeStr(%sz1)-1
sz1 CATSTR <_imp__&Win32API>,< PROTO >,sz1 sz1
call DWORD PTR [_imp__&Win32API] ENDM
下面iWin32i可以根据情况生成对ansi或者UNICODE的调用,前提是定义UNICODE=0或者TRUE...
iWin32i Macro Win32API:REQ,args:VARARG IF UNICODE
iWin32 Win32API&W,
iWin32 Win32API&A,
注意这个宏并没有参数检查,如果你不熟悉APi建议不要使用,你可以用masm包自带的工具
转换头文件来避免产生jmp tabel...如果你喜欢宏,那么就用我这种方式.
宏不同于封装,我们可以用他来简化我们的工作而又可以清楚知道将产生什么代码,为什么 不用呢?