文档章节

学 Win32 汇编[34] - 宏汇编(1)

涂孟超
 涂孟超
发布于 2014/09/26 15:37
字数 1184
阅读 5
收藏 0
点赞 0
评论 0

从接触 C 语言时, 我就不大喜欢宏; 但为了看懂别人的代码也不得不去了解.

宏可定义在源程序的任意位置, 但一般放在 .data 前面.
有些简单的宏可以用 equ、textequ 或 = 来代替, 但宏有更复杂的功能.

"宏" 的本质是 "替换", 但又像极了 "子过程";
所以即有宏过程(macro procedure)、也有宏函数(macro function).
它既以有参数(可以是: 常数、变量、寄存器、指令、表达式), 有时也需要像子过程一样声明.
宏可以指定哪些参数是必须的, 还可以给参数默认值.

宏可以包含数据(.data)和代码(.code)、还可以嵌套.
宏中的注释使用 ;; 如果只用 ; 将会被一起替换到代码中.

宏的功能很强大, 现在常用的 PrintDec、PrintHex、PrintString、PrintText 等等都是宏.
再强大它也只是 "文本替换".

"宏" 和 "子程序" 相比:
1、宏展开后顺序执行, 不像调用子程序跳来跳去, 这样程序会更 "快";
2、宏展开后会让代码量增大, 导致程序变 "大".

一个简单的宏:
; Test34_1.asm
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

;定义一个 mExit 宏
mExit macro
    PrintLine
    ret
endm

.code
sum proc v1, v2, v3
    mov eax, v1
    add eax, v2
    add eax, v3
    ret
sum endp
;
main proc
    invoke sum, 11, 22, 33
    PrintDec eax ;66
    ;PrintLine
    ;ret
    mExit ;mExit 将被替换为上面两行代码
main endp
end main

 
 
 
 
 

 

 

  

一个代替求和函数的宏:
; Test34_2.asm
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

mSum macro v1, v2, v3
    mov eax, v1
    add eax, v2
    add eax, v3
endm

.code
main proc
    mSum 11, 22, 33
    PrintDec eax ;66
    PrintLine
    mSum 11, 22, 33, 44, 55 ;多余的参数会被忽略
    PrintDec eax ;66
    PrintLine
    ret
main endp
end main

 
 
 
 
 

 

 

  

宏参数的默认值:
; Test34_3.asm
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

;参数 v1、v2 通过 REQ 标识说明是必备参数
;参数 v3、v4 给出了默认值
mSum macro v1:req, v2:req, v3:=<33>, v4:=<44>
    mov eax, v1
    add eax, v2
    add eax, v3
    add eax, v4
endm

.code
main proc
    mSum 11, 22
    PrintDec eax ;110
    PrintLine
    ret
main endp
end main

 
 
 
 
 

 

 

  

EXITM: 退出宏
; Test34_4.asm
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

mPrint macro
    PrintText '第一行'
    PrintText '第二行'
    exitm
    PrintText '第三行'
endm

.code
main proc
    mPrint ;只会输出前两行
    ret
main endp
end main

 
 
 
 
 

 

 

  

PURGE: 取消宏
; Test34_5.asm
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

mPrint macro
    PrintText '第一行'
    PrintText '第二行'
    PrintText '第三行'
    PrintLine
endm

.code
main proc
    mPrint
    mPrint
    purge mPrint ;可用逗号隔开取消多个宏
    mPrint       ;这个宏不会展开了
    ret
main endp
end main

 
 
 
 
 

 

 

  

宏中 local 的使用:
; Test34_6.asm
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

;从三个数中求最大数的宏
mMax macro v1, v2, v3
    LOCAL L1, L2 ;;如没有这句, 宏在多次展开时会让 L1、L2 重名, 这样宏会把标号名称协调好
    mov eax, v1
    cmp eax, v2
    jge L1
    mov eax, v2
L1: cmp eax, v3
    jge L2
    mov eax, v3
L2:
endm

.code
main proc
    mMax 11, 22, 33
    PrintDec eax  ;33
    ret
main endp
end main

 
 
 
 
 

 

 

  

灵活的参数, 用到 & 操作符:
; Test34_7.asm
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

;求最数中的最大值:
mMax macro v1, v2
    LOCAL L1
    mov eax, v1
    cmp eax, v2
    jge L1
    mov eax, v2
L1:
endm

;求最数中的最小值:
mMin macro v1, v2
    LOCAL L1
    mov eax, v1
    cmp eax, v2
    jle L1
    mov eax, v2
L1:
endm

;能把 JGE 或 JLE 做参数:
mCom1 macro XX, v1, v2
    LOCAL L1
    mov eax, v1
    cmp eax, v2
    XX L1
    mov eax, v2
L1:
endm

;能通过参数让 J*E 变为 JGE 或 JLE:
mCom2 macro X, v1, v2
    LOCAL L1
    mov eax, v1
    cmp eax, v2
    J&X&E L1    ;;这里用到特殊操作符 &
    mov eax, v2
L1:
endm

.code
main proc
    mMax 11, 22
    PrintDec eax ;22
    
    mMin 11, 22
    PrintDec eax ;11
    
    mCom1 JGE, 11, 22
    PrintDec eax ;22
    
    mCom1 JLE, 11, 22
    PrintDec eax ;11
    
    mCom2 G, 11, 22
    PrintDec eax ;22
    
    mCom2 L, 11, 22
    PrintDec eax ;11
    ret
main endp
end main

 
 
 
 
 

 

 

  

特殊操作符: &、<>、%、!
&  ;替换操作符
<> ;字符串传递操作符
%  ;表达式操作符, 也用于得到一个变量或常量的值
!  ;转义操作符

 
 
 
 
 

 

 

  
; Test34_8.asm .386 .model flat, stdcall include windows.inc include kernel32.inc include masm32.inc include debug.inc includelib kernel32.lib includelib masm32.lib includelib debug.lib ;自定义的宏 mPrint macro Text PrintText '* &Text& *' endm .code main proc ;该宏会把参数直接替换过去 mPrint 1234 ;* 1234 * ;要保证参数的完整应该使用 <> mPrint 12,34 ;* 12 * mPrint <12,34> ;* 12,34 * ;需要计算结果应该使用 %() mPrint 34+12 ;* 34+12 * mPrint %(34+12) ;* 46 * ;用到 &、<、>、%、! 应该使用 ! 转义 mPrint 10 !% 2 = %(10/2)!! ;* 10 % 2 = 5! * ret main endp end main

本文转载自:http://www.cnblogs.com/del/archive/2010/04/29/1724459.html

共有 人打赏支持
涂孟超
粉丝 12
博文 2004
码字总数 14107
作品 0
深圳
程序员
Win32汇编语言核心

一. Win32汇编源程序的结构 hello world程序 .386 .model flat, stdcall option casemap: none include windows.inc include user32.inc includelib user32.lib include kernel32.inc inclu......

呼噜呼噜睡翻天 ⋅ 2014/04/02 ⋅ 0

win32汇编和x64汇编?

win32汇编升到winx64汇编,转型容易吗?我指的是会win32汇编,还学x64汇编吗?我是初学,能不能直接学x64汇编语言,请推荐本书?

IIOWE ⋅ 2014/10/01 ⋅ 3

为什么破解要学win32汇编?

听说破解要学win32汇编,写壳也要用win32汇编?为什么呢?不学不能学破解吗?

IIOWE ⋅ 2014/10/02 ⋅ 13

Win32汇编开发环境介绍和RadAsm简明教程

Win32汇编开发环境介绍和RadAsm简明教程 现在很多朋友都在学习汇编语言,一方面汇编语言是大学计算机课程的必修课,另一方面则是为了从其它语言转到汇编语言来,无论什么原因,我认为学习汇编...

nothingfinal ⋅ 2009/08/01 ⋅ 0

[Beautifulzzzz的博客目录] 快速索引点这儿O(∩_∩)O~~,红色标记的是不错的(⊙o⊙)哦~

3D相关开发 [direct-X] 1、direct-X最小框架 [OpenGL] 1、环境搭建及最小系统 [OpenGL] 2、企业版VC6.0自带的Win32-OpenGL工程浅析 51单片机 [51单片机] 1602液晶显示控制代码 [51单片机] 1...

史迪奇2号 ⋅ 2017/08/01 ⋅ 0

如何在 Windows 下编译 OpenSSL?

OpenSSL是一个开源的第三方库,它实现了SSL(Secure SocketLayer)和TLS(Transport Layer Security)协议,被广泛企业应用所采用。对于一般的开发人员而言,在http://slproweb.com/product...

鉴客 ⋅ 2013/12/24 ⋅ 1

MASM32 SDK

MASM32 SDK是不同工具软件的大集合,它的汇编编译器用的是微软MASM软件包中的Ml.exe,资源编译器和32位链接器使用的是Microsoft Visual Studio中的Rc.exe和Link.exe,同时包含了Microsoft V...

匿名 ⋅ 2011/05/04 ⋅ 1

函数式编程如何能在常规软件开发中占一席之地

除非你生活中与世隔绝的深山老林里,否则你应该知道,在众多的所谓顶级编程高手(alpha geeks)中,函数式编程是十分盛行的。也许你已经使用了某种函数式编程语言。如果你是在使用很传统的编程...

oschina ⋅ 2012/08/21 ⋅ 16

王小波的计算机水平到底有多好?

原文出处:知乎 导读:有网友在知乎上提问: 王小波的计算机水平到底有多好,在王小波自己的小说中,王小波非常骄傲地说,写书的软件都是自己编写的,王小波是自学的还是教的?都会什么语言?...

知乎 ⋅ 2017/05/05 ⋅ 0

远程桌面控制VC源码剖析

一、引语 这是个VC6.0的远程桌面控制软件,主要功能是桌面控制、支持多种压缩方式、可调整网格空间数目以及色彩模式选择。源码我也不知道从何而来了,今天整理硬盘无疑间发现的。软件中作者没...

toil ⋅ 2012/08/08 ⋅ 5

没有更多内容

加载失败,请刷新页面

加载更多

下一页

如何优雅的编程——C语言界面的一点小建议

我们鼓励在编程时应有清晰的哲学思维,而不是给予硬性规则。我并不希望你们能认可所有的东西,因为它们只是观点,观点会随着时间的变化而变化。可是,如果不是直到现在把它们写在纸上,长久以...

柳猫 ⋅ 29分钟前 ⋅ 0

从零手写 IOC容器

概述 IOC (Inversion of Control) 控制反转。熟悉Spring的应该都知道。那么具体是怎么实现的呢?下面我们通过一个例子说明。 1. Component注解定义 package cn.com.qunar.annotation;impo...

轨迹_ ⋅ 29分钟前 ⋅ 0

系统健康检查利器-Spring Boot-Actuator

前言 实例由于出现故障、部署或自动缩放的情况,会进行持续启动、重新启动或停止操作。它可能导致它们暂时或永久不可用。为避免问题,您的负载均衡器应该从路由中跳过不健康的实例,因为它们...

harries ⋅ 31分钟前 ⋅ 0

手把手教你搭建vue-cli脚手架-详细步骤图文解析[vue入门]

写在前面: 使用 vue-cli 可以快速创建 vue 项目,vue-cli很好用,但是在最初搭建环境安装vue-cli及相关内容的时候,对一些人来说是很头疼的一件事情,本人在搭建vue-cli的项目环境的时候也是...

韦姣敏 ⋅ 41分钟前 ⋅ 0

12c rman中输入sql命令

12c之前版本,要在rman中执行sql语句,必须使用sql "alter system switch logfile"; 而在12c版本中,可以支持大量的sql语句了: 比如: C:\Users\zhengquan>rman target / 恢复管理器: Release 1...

tututu_jiang ⋅ 55分钟前 ⋅ 0

Nginx的https配置记录以及http强制跳转到https的方法梳理

Nginx的https配置记录以及http强制跳转到https的方法梳理 一、Nginx安装(略) 安装的时候需要注意加上 --with-httpsslmodule,因为httpsslmodule不属于Nginx的基本模块。 Nginx安装方法: ...

Yomut ⋅ 今天 ⋅ 0

SpringCloud Feign 传递复杂参数对象需要注意的地方

1.传递复杂参数对象需要用Post,另外需要注意,Feign不支持使用GetMapping 和PostMapping @RequestMapping(value="user/save",method=RequestMethod.POST) 2.在传递的过程中,复杂对象使用...

@林文龙 ⋅ 今天 ⋅ 0

如何显示 word 左侧目录大纲

打开word说明文档,如下图,我们发现左侧根本就没有目录,给我们带来很大的阅读障碍 2 在word文档的头部菜单栏中,切换到”视图“选项卡 3 然后勾选“导航窗格”选项 4 我们会惊奇的发现左侧...

二营长意大利炮 ⋅ 今天 ⋅ 0

智能合约编程语言Solidity之线上开发工具

工具地址:https://ethereum.github.io/browser-solidity/ 实例实验: 1.创建hello.sol文件 2.调试输出结果

硅谷课堂 ⋅ 今天 ⋅ 0

ffmpeg 视频格式转换

转 Mp4 格式 #> ffmpeg -i input.avi -c:v libx264 output.mp4#> ffmpeg -i input.avi -c:v libx264 -strict -2 output.mp4#> ffmpeg -i input.avi -c:v libx264 -strict -2 -s 1......

Contac ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部