吾爱汇编

 找回密码
 立即注册

QQ登录

绑定QQ避免忘记帐号

查看: 3938|回复: 6

[汇编] MASM 宏汇编

[复制链接]
李沉舟 发表于 2018-4-5 10:51 | 显示全部楼层 |阅读模式

P.S.
论坛的编辑器一直感觉不是很好用,俺今天突然发现在博客园写好了以后,直接复制进来,发现排版完全OK,而且在编辑器里面看STYLE是无比炫酷啊。

宏是一段汇编语句序列。定以后,在程序中进行宏调用,则由编译器在编译器前进行展开。

1.宏定义和宏调用
宏定义一般用一对宏汇编伪指令MACRO和ENDM完成,格式如下:
宏名  MACRO  [形参表]
    ……        ;宏定义体
ENDM

宏名必须是合法的标识符,同一源程序中应该唯一。宏定义体中不仅可以是硬件指令组成的执行性语句序列,还可以是伪指令组成的指示性语句序列。可选的形参表给出了宏定义中用到的形式参数,各个形参之间用半角逗号进行分割。
请看下面这段程序:

[url=] copycode.jpg [/url]
.386.model    flat,stdcalloption    casemap:noneinclude        windows.incinclude        kernel32.incinclude        user32.incincludelib    kernel32.libincludelib    user32.libShowMessage    macro    szText,szCaption    push    MB_OK    push    offset szCaption    push    offset szText    push    0    call    MessageBoxendm.dataszS1        db    '吞风吻雨葬落日未曾彷徨,欺山赶海践雪径也未绝望',0szS2        db    '难念的经',0.codeMain    proc    ShowMessage    szS1,szS2    invoke    ExitProcess,0    retMain    endp_START:    call    Mainend    _START[url=] copycode.jpg [/url]


                               
登录/注册后可看大图

在编译时,编译器搜索所以宏调用,并用相应的宏定义体进行替换。宏定义的语法是否错误是不检查的,这类似于C语言中的#define,宏展开后由编译器进行语法检查。

查看这段代码编译后的反汇编,可以看到:

                               
登录/注册后可看大图

2.宏的参数和宏的操作符
宏的参数功能强大,数量不限,可以是常数,变量,储存单元,指令(操作码),也可以是表达式。宏的参数还可以设置默认值。
运用宏海需要一些宏操作符的配合,如下:
宏操作符作用或含义
&替换操作符,用于将参数与其他字符分开。如果参数紧接在其他字符之前或之后,或者参数出现在带引号的字符串中,必须使用该伪操作符
<>字符串传递操作符,如果字符串包含逗号,空格等,则必须使用该对操作符,以保证传递完整性
!转义操作符,用于表明后一个字符是一般字符,不具有特殊含义
%表达式操作符,用于宏调用中表示将后跟的一个表达式的值作为实参,而不是将表达式本身作为参数
;;宏注释符,用于表示在宏定义的注释。在展开中不出现。
:=设定参数默认值
请看如下示例程序:
[url=] copycode.jpg [/url]
.386.model    flat,stdcalloption    casemap:noneinclude        windows.incinclude        kernel32.incinclude        user32.incincludelib    kernel32.libincludelib    user32.libText    macro    string,define    define    byte    '&string&',0endm.dataText    <Assembly Is Very Good!!>,<szText>Text    <Title>,<szTitle>.codeMain    proc    invoke    MessageBox,0,offset szText,offset szTitle,MB_OK    invoke    ExitProcess,0Main    endp_START:    call    Mainend    _START[url=] copycode.jpg [/url]

首先,我们定义了一个名为Text的宏,该宏有两个参数,第一个参数表示字符串内容,第二个参数表示定义字符串的标识符。在定义"Assembly is very Good!"字符串时,我使用了两个感叹号,为何?假如我们直接使用"Text <Assembly Is Very Good!>,<szText>"而不在尾部加两个!时会发生什么呢?!号表示后一个字符不具有特殊意义,那么>就不再表示字符串传递符号了。而且,宏定义体我使用了&&操作符,因为我在''里面使用了参数,如果不指明,那么'string'就会变成普通的字符串,不具备任何其它意义。
3.宏的伪指令
我们考虑如下宏:
[url=] copycode.jpg [/url]
Bigger    macro    Num1,Num2    mov    eax,Num1    cmp    eax,Num2    jg    next    mov    eax,Num2next:endm[url=] copycode.jpg [/url]

这段Bigger宏有什么作用呢?它接受两个参数,并将较大的那个参数放入EAX。
如果我们在同一个子程序里面多次调用它会发生什么呢?调用一次呢?多次调用时,错误如下:
Test.asm(26) : error A2005: symbol redefinition : next
Bigger(5): Macro Called From
Test.asm(26): Main Line Code
为什么呢?因为next标号,多次调用宏时,宏被重复展开,next标号被重复定义,同一个子程序里面怎么能出现多个同名标号呢?这自然会引发错误,那么如何改进呢?
我们可以在宏里面使用LOCAL伪指令。
LOCAL伪指令使用格式如下:
LOCAL 标号列表
改进之后的宏如下:
[url=] copycode.jpg [/url]
Bigger    macro    Num1,Num2    LOCAL    next    mov    eax,Num1    cmp    eax,Num2    jg    next    mov    eax,Num2next:endm[url=] copycode.jpg [/url]

您可以尝试在同一个子程序里面重复使用试试看还会出现错误吗?

程序中有时要连续重复一段相同或基本相同的语句,这时可以使用重复汇编来完成。重复汇编一样是在编译前进行展开的。重复汇编伪指令有3个:REPEAT/FOR/FORC,3条汇编伪指令的区别在于如何制定重复次数。

1.REPEAT
我们可以用重复汇编定义'0' - '9',请看以下示例程序:
[url=] copycode.jpg [/url]
option    casemap:noneinclude        windows.incinclude        kernel32.incinclude        user32.incincludelib    kernel32.libincludelib    user32.libasc    =    '9'.dataszNums        db    asc        repeat    '9' - '0'            asc  = asc - 1            db    asc        endm        db    0.codeMain    proc    invoke    MessageBox,0,offset szNums,offset szNums,MB_OK    invoke    ExitProcess,0Main    endp_START:    call    Mainend    _START[url=] copycode.jpg [/url]


2.FOR
FOR伪指令按照实参表个数进行重复汇编,实参用<>括起来,并用,分割。比如,我们可以不使用pushad,而换一种方式压入所有寄存器。
源代码如下:
    FOR    reg32,<eax,ebx,ecx,edx,edi,esi,ebp>        push    reg32    ENDM

3.FORC
FORC伪指令按字符串字符个数重复汇编。字符串可以用<>括起来,也可以不括,按照从左到右的顺序,每一次重复用一个字符替换形参。比如,我们可以写一段代码把一串10进制数字转换为字符串类型。
[url=] copycode.jpg [/url]
.386.model    flat,stdcalloption    casemap:noneinclude        windows.incinclude        kernel32.incinclude        user32.incincludelib    kernel32.libincludelib    user32.lib.dataszBuf        db    256    dup(0).codeMain    proc    mov    esi,offset szBuf    FORC    num,<0123456789>        mov    byte ptr[esi],num        add    byte ptr[esi],'0' - 0        inc    esi    ENDM    invoke    MessageBox,0,offset szBuf,offset szBuf,MB_OK    invoke    ExitProcess,0Main    endp_START:    call    Mainend    _START[url=] copycode.jpg [/url]


评分

参与人数 6HB +4 THX +3 收起 理由
消逝的过去 + 2
zxjzzh + 1 [吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守!
后学真 + 1 [吾爱汇编论坛52HB.COM]-感谢楼主热心分享,小小评分不成敬意!
yexing + 1
agan8888 + 1
2323816 + 1

查看全部评分

吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
帝爵 发表于 2019-12-26 13:08 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
yangfe1520 发表于 2020-3-1 00:49 | 显示全部楼层

我以为是MASM引擎写的呢!
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
superfasst 发表于 2021-11-9 23:04 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
2323816 发表于 2022-1-15 15:17 | 显示全部楼层

不明觉厉,先膜拜下
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
后学真 发表于 2022-10-8 16:19 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
丘风 发表于 2024-1-16 16:46 | 显示全部楼层

谢谢,好人一生平安
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

警告:本站严惩灌水回复,尊重自己从尊重他人开始!

1层
2层
3层
4层
5层
6层
7层

免责声明

吾爱汇编(www.52hb.com)所讨论的技术及相关工具仅限用于研究学习,皆在提高软件产品的安全性,严禁用于不良动机。任何个人、团体、组织不得将其用于非法目的,否则,一切后果自行承担。吾爱汇编不承担任何因为技术滥用所产生的连带责任。吾爱汇编内容源于网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除。如有侵权请邮件或微信与我们联系处理。

站长邮箱:SharkHeng@sina.com
站长QQ:1140549900


QQ|RSS|手机版|小黑屋|帮助|吾爱汇编 ( 京公网安备11011502005403号 , 京ICP备20003498号-6 )|网站地图

Powered by Discuz!

吾爱汇编 www.52hb.com

快速回复 返回顶部 返回列表