`
zzc1684
  • 浏览: 1224856 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

从接触 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
分享到:
评论

相关推荐

    WIN32汇编程序源码级调试_VS2019_vs2019win32汇编_vs2019win32汇编_Win32汇编程序_汇编语言

    本文将详细探讨"WIN32汇编程序源码级调试_VS2019"这一主题,包括如何在Visual Studio 2019(VS2019)环境下编写和调试Win32汇编程序,以及如何实现一个学生管理系统。 首先,让我们了解Win32汇编。Win32汇编是针对...

    Win32汇编 Win32汇编

    1. **指令集**:Win32汇编基于Intel x86架构,使用一系列指令来控制处理器执行操作,如数据移动、算术运算、逻辑运算、跳转和条件判断等。 2. **寄存器**:在x86架构中,有多个通用寄存器(如EAX、EBX、ECX、EDX、...

    Win32汇编语言教程

    【Win32汇编语言教程】是一篇针对深入学习Win32平台汇编语言编程的指导性文章。在计算机编程领域,尽管C语言是开发Win32应用程序的常见选择,但在特定情况下,如系统底层操作、性能优化或病毒分析等,汇编语言显得...

    win32汇编语言集成开发环境

    1. **Win32 API**:Win32 API是微软提供的一个应用程序接口,允许开发者创建在Windows 32位操作系统上运行的应用程序。它包含了各种函数调用,涵盖了窗口管理、图形设备接口、文件系统操作等多个方面,是编写Win32...

    win32汇编服务管理程序

    1. `ServicesManager.Inc`:这可能是一个包含汇编语言宏定义和服务管理相关常量的头文件,用于简化代码编写和提高代码可读性。 2. `disabled.bmp`、`stop.bmp`、`pause.bmp`、`start.bmp`:这些是位图文件,可能...

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

    1. **指令集**:Win32汇编基于x86架构,包含了如MOV、ADD、SUB、JMP等基本指令,以及处理浮点数的XMM和YMM寄存器的SSE和AVX指令集。 2. **寄存器**:x86架构有多种寄存器,如EAX、EBX、ECX、EDX等,它们是程序执行...

    win32汇编语言编译器

    《深入探索Win32汇编语言编译器》 在计算机科学领域,汇编语言是一种低级编程语言,它与机器指令系统紧密相关,每条汇编指令通常对应一个特定的机器码。对于Windows 32位操作系统而言,x86架构的汇编语言尤为重要,...

    win32汇编开发工具包

    **win32汇编开发工具包详解** 在计算机科学领域,汇编语言是一种低级编程语言,它直接对应于机器代码,每一行汇编指令都代表着一个或几个特定的CPU操作。win32汇编开发工具包是针对Windows 32位操作系统设计的汇编...

    用MasmPlus 学习Win32 汇编

    MasmPlus是Masm的升级版,提供了更丰富的宏定义和更友好的语法,使得编写Win32汇编程序变得更加便捷。它支持Intel x86架构下的32位指令集,能够生成符合Windows API规范的可执行文件。在MasmPlus中,我们可以直接...

    Win32汇编项目模板 Win32 Assembly Project

    1. **Win32汇编语言**: - Win32汇编是使用Microsoft的MASM(Microsoft Assembler)或其他类似的汇编器,如NASM或TASM,来编写针对Windows API的汇编代码。它允许直接访问操作系统级别的功能,如窗口创建、事件处理...

    汇编语言实用教程-基于Win32编程

    本书主要内容包括:80x86指令系统、寻址方式、宏指令与伪指令、汇编语言格式与程序结构、分支程序设计、循环程序设计、子程序设计、宏汇编技术、系统功能调用与使用方法、I/O程序设计方法与中断程序设计。...

    win32 汇编教程

    1. **masm.chm**:这可能是一个帮助文件,包含了关于MASM汇编器的详细使用指南,包括语法、宏指令、错误处理、链接器选项等内容。学习这个文件可以帮助你更好地理解和使用MASM进行汇编编程。 2. **说明.htm**:这个...

    Win32汇编教程

    **Win32汇编教程** Win32汇编语言是一种低级编程语言,它与计算机硬件的交互最为直接,能够实现对系统资源的精细控制。本教程将深入探讨Win32汇编的基本概念、语法以及在Windows操作系统环境下的应用。 **1. 汇编...

    win32汇编写的驱动程序框架

    对于"win32汇编写的驱动程序框架",我们探讨的是一个使用低级语言——汇编语言构建的驱动程序基础架构,特别地,这个框架是用RADASM这款汇编器编写的。 首先,我们要理解汇编语言。汇编语言是一种面向机器的语言,...

    win32asm例子

    【win32汇编MASM】是编程领域中一个专门针对Windows 32位系统进行程序开发的技术。MASM(Microsoft Assembler)是微软提供的一个汇编语言编译器,它支持Intel x86架构下的汇编语言编程,广泛应用于低级别系统编程、...

    Win32汇编(RadAsm)简明教程第二版

    总的来说,《Win32汇编(RadAsm)简明教程第二版》是一个全面介绍如何使用RadAsm进行Win32汇编编程的教程,通过阅读"Win32IDEandRadAsmV2.chm"的文档,配合"ReadMe.txt"中的说明和"code"目录中的实例,读者可以逐步...

    win32 汇编笔记精华

    1. **指令集架构(ISA)**:Win32汇编基于Intel x86架构,这是最常见的个人计算机处理器架构之一,包括一系列的指令,如数据移动、算术运算、逻辑操作等。 2. **寄存器**:x86架构有多个通用寄存器,如EAX、EBX、...

Global site tag (gtag.js) - Google Analytics