首页
社区
课程
招聘
[原创]Four-F高级字符串宏修正版
发表于: 2006-3-5 01:14 9123

[原创]Four-F高级字符串宏修正版

2006-3-5 01:14
9123

原版为Four-F版权所有, 修正及添加的内容为thebutterfly版权所有.转载请保留
这个宏原作者为Four-F(KmdKit的作者), 我试用后觉得效果不错, 但是这个宏中有一些Bug和缺憾, 所以我抽出一点时间做了修正, 同时又加上了不少新的内容, 这里提供给大家, 以方便大家的MASM编程
"原版"程序有4, 000多行, 做了修正后差不多有6, 000行了, 所以就不贴出, 大家可以从附件下载

使用说明:
(一)原作者说明概要
这个宏为方便在MASM的汇编源程序里定义字符串而设计, 可以方便的定义各式各样的字符串, 另外为了适应编写驱动程序的需要加上了Unicode字符串支持

1.概览
我们要定义字符串时通常会采用这样的方式:

.data
szStr    DB   "Hello, World", 0
......
......
.code
.....
invoke  MessageBox, NULL, ADDR szStr, ADDR szStr, MB_OK
....
这是标准的定义方式, 但是阅读程序时会很不方便, 而且并不是每一个字符串都需要一个有意义的名字

而现在可以采用这种方式:

.code
invoke  MessageBox, NULL, $CTA0("Hello World"), $CTA0("Hello World"), MB_OK

非常方便吧

这个文件提供了一系列类似的宏, 可以方便的完成定义字符串的任务

2.使用说明
宏的名字由以下几个字符组成:
$  C  T  A  W  0(数字0非字母o)
例如上面提到的$CTA0由"$", "T", "A", "0"组成, 它们含义如下:

$  有$打头的是宏函数, 如$CTA0, 调用方式为 宏名(参数1, 参数2...) 没有$打头的的是普通的宏, 它们只是起到定义字符串的作用

T  每个宏都有, 代表sTring, 字符串

A  代表Ansi, 如果一个宏名中有A, 这个宏定义的字符串是Ansi字符串

W  代表Widechar, 和A相对, 如果一个宏名中有W, 它定义的字符串是Unicode的

0  代表字符串自动以0结尾, 只有名字含"0"的宏才有定义空字符串的功能, 如果你用名字不含0的宏来定义空字符串会编译错误

C  代表Const, 含C的宏会在.const段中定义字符串, 而不含C的会在.data中定义

例如: $CTW0宏函数功能是在.const段中定义一个以0结尾的Unicode字符串
TA 功能是在.data段中定义一个Ansi字符串

如果一个宏名字中没有A或W, 这个宏定义的到底是Ansi字符串还是Unicode字符串则取决于是否定义UNICODE常量

通用语法:
对于宏:
宏名   ["字符串"], [字符串名], [对齐方式]
对于宏函数
宏名(["字符串"], [字符串名], [对齐方式])

说明:a.字符串必须用双引号括起
b.字符串名和对齐方式可以颠倒, 可以空缺
c.对齐方式是WORD, DWORD或者1, 2, 4, 8等

3.功能特色
a.字符串支持转义符, 如:
CTA0  "Hello\nWorld"
会显示为
Hello
World

支持的转义符有\n \r \t \a \b \l \f等

b.能够自动找出重复定义的字符串
如定义两个Hello时, 第2次会自动查出并返回首次定义的字符串

4.已知限制和缺点
a.CreateFile会自动变成CreateFileA, 这是由于masm编译器的特性
CreateFile  EQU  <CreateFileA>

b.Unicode字符串最大支持47个字符, 否则会出错

c.Unicode字符串不支持中文(这个在我的修正版中得到初步的解决)

;-----------------------------------------------------------------------------------

(二)修正说明
1. 字符串支持新的转义符\u, 可以直接在引号内定义AscII码, 类似于C语言的\x
例如:CTA0  "\u41h\u42h\u43h"
等价于
    CTA0  "ABC"
A的AscII码为41h, B为42h, C为43h
注意AscII码必须是16进制的且必须以h或大写的H结尾

2. Unicode字符串支持64个字符(花了我好久)

3. Unicode间接支持中文(使用\uxxxxh定义中文的Unicode码)

例如 CTW0  "\u6211h\u7231h\u4F60h"

这是什么?嘻嘻, 大家试试就知道了

4.增加了好多宏
如$FTA0等, Dos下用, Windows下用处不大, 就不说了

/////////////////////////////////////////////////
//欢迎大家找出Bug和提出建议                    //
/////////////////////////////////////////////////

附一个例子:
.386
.model flat, stdcall
.option casemap:none

include windows.inc
include user32.inc
includelib user32.lib

include String.inc

.const
CTA  "Hello\0", szaHello   ;定义一个名为szaHello的字符串, 这里用的是不带0的宏
CTW0 "Hello", szwHello

.code
start:
invoke MessageBoxA, NULL, OFFSET szaHello, $CTA0("Title"), MB_OK
invoke MessageBoxW, NULL, OFFSET szwHello, $CTW0("Title"), MB_OK
ret
END start


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (17)
雪    币: 235
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
先回一个~~~

慢慢看~~~~~~~~~~~~~

好人,好人啊~
2006-3-5 02:27
0
雪    币: 235
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
晕。。。。

$CTW0

最后一个字符是0(零),试了半天才看出来
2006-3-5 02:31
0
雪    币: 291
活跃值: (213)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
4
最初由 lemony 发布
晕。。。。

$CTW0

最后一个字符是0(零),试了半天才看出来


我已经提到过了
数字"0"而非字母"o"
因为它代表自动加上字符串结尾的0, 所以是数字0而非字母
2006-3-5 02:41
0
雪    币: 235
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
问题又来了~~~

masm中的wsprintf好像不能格式化unicode字符~~~

但是微软又没有提供wsprintfW这个函数~~~~

如何解决?
2006-3-5 02:42
0
雪    币: 291
活跃值: (213)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
6
user32.dll的导出表中有wsprintfW函数
2006-3-5 02:51
0
雪    币: 235
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
我刚才查到了

并且在代码中声明
wsprintfW PROTO C :DWORD,:VARARG

编译可以通过,但是链接会失败
error LNK2001: unresolved external symbol _wsprintfW
2006-3-5 02:53
0
雪    币: 235
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
难道要手动导入该函数?

编辑:

晕,今天的发贴数用完了~~~~

刚才我用SDK的user32.lib替换了一下masm的lib

编译通过,也可以正常运行~~

但是两个lib大小差好多哦~~

masm有400多K
SDK的只有100多K

不知道会不会出问题
2006-3-5 02:55
0
雪    币: 291
活跃值: (213)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
9
user32.inc里压根没有声明wsprintfW函数, 所以导入库中也没有这个函数
如果不想替换库文件就只有手动导入了
2006-3-5 03:04
0
雪    币: 234
活跃值: (370)
能力值: ( LV9,RANK:530 )
在线值:
发帖
回帖
粉丝
10
好像也没怎么方便,可能是 不习惯
2006-3-5 17:08
0
雪    币: 291
活跃值: (213)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
11
阅读代码时会很方便, 不用来回翻页找字符串定义
另外定义Unicode字符串会很方便, 试想这种方式

CTW0 "Hello Masm and Assemble Language", szMsg



szMsg   dw  'H', 'e', 'l', 'l', 'o', ' ', 'M', 'a', 's', 'm', ' ', 'a', 'n', 'd', ' ', 'A', 's', 's', ........

相比, 哪个方便?
2006-3-5 18:15
0
雪    币: 290
活跃值: (645)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
good,support!
2006-3-5 21:30
0
雪    币: 214
活跃值: (70)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
13
2006-3-6 13:31
0
雪    币: 179
活跃值: (131)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
14
好东西,支持
2006-3-6 18:47
0
雪    币: 238
活跃值: (326)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
15
如此好文,怎能不顶。
2006-3-8 14:12
0
雪    币: 291
活跃值: (213)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
16
2006.08.17更新
changes:
- 彻底去除了Unicode字符串不能超过64字符的限制
- 部分小Bug修补
- 原文件开头的教程被单独分离到tutorial.txt中,但保留版权说明

这一组宏极大的方便了在MASM中定义字符串,特别是Unicode字符串的支持。主要特色:支持转义符(\n和C++的有一点不同);自动消除重复的字符串(Four-F原创),即当一个字符串被定义后,
如果再次遇到相同的定义会自动去引用原来的而不会再次定义一份(可以控制这种机制是否起作用)

唯一的遗憾是不能直接支持Unicode中文字符串,这是MASM宏的能力所限
定义中文字符串要用间接方式,即用\u转义符定义中文字符的Unicode编码

欢迎提出改进意见以及指出Bug,感谢大家的支持
上传的附件:
2006-8-17 16:33
0
雪    币: 179
活跃值: (131)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
17
更新了,好~
2006-8-17 16:43
0
雪    币: 216
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
18
真是好东西啊,谢谢啦!!!
2006-8-18 12:53
0
游客
登录 | 注册 方可回帖
返回
//