ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

汇编学习笔记(13) - 宏指令(MASM)

2020-02-04 23:00:51  阅读:575  来源: 互联网

标签:汇编 13 定义 ENDM MASM DB MOV AX BX


结构

    说明:

    是一堆数据的定义的集合

    基本格式:

    结构名称       STRUC       字段的定义     结构名称       ENDS              举例:     STUDENT    STRUC       ID       DW         ?       SCORE   DB          1       NAME     DB          'STUDENTNAME'     STUDENT    ENDS         

    定义变量:

    变量名         结构类型    < 参数表 >              举例:           S1     STDUENT        <1,50,'zhao'>       S2     STDUENT        <1,60,'zhang'>       S3     STDUENT        <1,70,'wang'>         

    结构使用:

    1. MOV AX, P1.ID              2. MOV BX, OFFSET P1            MOV AL, [BX].SCORE

    总结:

    使用起来还是和C/C++ 的结构比较类似的,实际上  P1.ID  和 [BX].SCORE 的两种引用方式本质上是汇编器帮我们转换了地址。         

记录

    说明:

    结构是将将一堆定义结合起来,方便管理,那么记录就是讲一个字或者一个字节拆分成各种按照位的定义     实际上记录就是一个字或者字节的按位定义,所以长度最长不超过16位,右对齐。         

    基本格式:

    记录名称       RECORD           字段1:位宽=初始值,字段2:位宽=初始值,….              举例:       ABCD    RECORD     AA:5=12, BB:3=6, CC:4=3                  内存结构:                    15  14  13  12  11  10  9   8   7   6   5   4   3   2   1   0       0   0   0   0   aa  aa  aa  aa  aa  bb  bb  bb  cc  cc  cc  cc         

    定义变量:

    变量名         结构类型    < 参数表 >              举例:                   S2     ABCD        <1,2,3>               S1     ABCD        <1,2,3>               S3     ABCD        <3,2,1>         

    记录使用:

    WIDTH       返回一个记录整体的位宽或者一个字段的位宽       MOV AX, WIDTH ABCD       MOV AX, WIDTH AA                       MASK       返回对应字段的掩码       MOV BX, MASK AA;       BX = 0001111100000000B     

    总结:

    和结构的功能有点类似,相当于在字节尺度尺度上的结构定义,相当于定义 标志位, 而MASK 就是提取标志位的掩码。         

宏定义

    说明:

    宏定义的本质和C/C++ 一样就是字符替换,用定义的内容替换掉宏标识符         

    基本格式:

    宏名称      MACRO      参数1,参数2,………         local      标号1, 标号2 ……         标号1: xxxxx             xxxxx             xxxxx         ENDM

        举例:

      M1    MACRO      OPR, X, Y           LOCAL          P1, P2           P1:         OPR    AX, BX               MOV  AX,  X               MOV  BX,  Y               TEST   AX, BX               JNZ   P1               JMP  P2           P2:         MOV AX, BX                     ENDM         

    宏的使用:

    M1      MOV, 5, 1     这条指令会被展开如下结果大致上就是字符替换              ??0001:    MOV   AX, BX                                MOV   AX, 5                      MOV   BX, 1                     TEST   AX, BX                     JNZ    ??0001                     JMP    ??0002     ??0002:   MOV  AX, BX              其中值得注意的是标号被替换成了  ??0001 ??0002   这是因为 宏如果在同一段代码里多次展开,标号也会跟着被多次展开,那么就会出现一段代码里同一个标号被多次定义,就会报错,所以如果在宏定义里面有标号定义,那么在 开头要使用 LOCAL 指令声明本地标号,这样汇编器会自动累加数字来代替标号     另外,使用的时候参数多传少传都可以,多传了就舍弃,少传了就默认用空代替,之后介绍的命令 IFB 可以判断参数是否为空         

    参数传递的说明:

  &     连接参数用的,应该与C中的用法差不多,通常用于字符拼接以及字符串中         定义:         JUMP   MACRO    CON,LAB              J&CON      LAB            ;;  这里就是将 字符 J 和 CON 的传入的内容拼接起来                 ENDM       使用:         JUMP     NZ, EXIT       展开为         JNZ  EXIT       同理如果是定义在'' 字符串中页需要用& 表明是参数       定义:         MSG MACRO A,B           A    DB 'MR.&B'           ENDM       使用                    MSG   A1,HELLO       展开为                    A1     DB  'MR.HELLO'                  <>  字符串原样传递,如果字符串中报个各种字符,比如空格 特殊字符等,就用 <> 包起来,                  汇编就会把他们统统当成一个完整字符串而不会去解析含义了                   比如   < 包含各种内    容的字符,串--//123!@#$%^ > 中间有逗号,如果不用<> 汇编器会以为是两个参数                  !    转义符号在上面的, 相当于c在字符串中的 \ , 这里比如 有一段字符串   1>2   ,如果用<> 包起来 就变成   <1>2>, 那就不对了,              汇编器会以为到1后边的> 就结束了,所以要用  <1!>2>, 用!来个后面的 > 转义.                  %  在参数传递的时候是可以传入表达式的, 用%() 包起来,就是告诉汇编器闯入的是表达式的值而不是标的是本身。               比如       定义:         MSG MACRO A,B                           A    DB 'MR.&B'                          ENDM       使用         MSG   A1, 1+2       展开为         A1     DB  'MR.1+2'                        使用                      MSG   A1, %(1+2)                  展开为                     A1     DB  'MR.3'

    其他说明:

    PURGE   消除宏定义       比如前面定义了 宏  MSG, 那么在使用 PURGE MSG 之后的代码里,MSG这个宏就不能使用了,但是之前还是能使用的。     EXITM   终止宏的展开       这个伪指令用在宏定义里面,当宏展开的时候遇到这个命令就停止展开了,相当于阶段宏的内容。

    总结:

    宏的功能有点像子过程调用,但是由于它是在汇编阶段就展开的,没有像CALL 一样的压栈转跳等的开销,所以实际上他比CALL高效,实际上就有点像C++ 中的 INLINE 函数。     宏中可以使用宏,宏定义中页可以嵌套定义宏,但是嵌套定义的宏,需要使用一次宏才会生效,比如       DEF     MACRO   A         A    MACRO                                        push    ax                               ENDM                     ENDM                  如果不使用DEF宏定义,那么DEF宏定义不会被展开,那么根本就没有 A的宏定义,如果顺序是这样的                DEF   DEF2       被展开为       DEF2  MACRO           PUSH AX          ENDM     这个使用宏定义中的宏定义才被真正定义     之后才可以使用DEF2的宏定义         

重复汇编

    说明:

    用途就是相当于写了个循环     如下场景       db     0       db     0       .       20 个这样的内容,目的是定义20个byte变量,或者说就是定义   BYTE    LIST[20]       .       db     0       db     0       那就可以用 重复汇编  宏指令了         

    基本格式:

  RPET     格式        REPT    NUM           XXXXXX                                   ENDM     说明          功能就是将里面的内容直接复制粘贴多少遍     比如         rept   5           db 0         endm       展开为                        db  0                        db  0                        db  0                        db  0                        db  0          可以用来定义数据   比如 BYTE LIST[20], 直接就是         rept  20         db  0         endm                          IRP     格式       IRP    待替换参数<参数表1,参数表2,参数表3,参数表4,参数表5,参数表6>         xxxxxxx         endm             说明       本质还是一样的,但是功能丰富了一点,在复制的时候,会逐一使用参数表内容替换待替换参数             比如       IRP   P1<1,2,3,4,5,6>         DB   P1         ENDM       展开为         DB 1                         DB 2                         DB 3                         DB 4                         DB 5                         DB 6                      IRPC             格式       IRPC   待替换参数,字符串           xxxxxxx         endm             说明       其实和IRP 是一样的,就是用参数表逐一替换,不同的是给出这里给出的参数是字符串,这个伪指令会用字符串的字符来逐一代替             比如       IRP   P1 abcdef         DB   P1         ENDM       展开为                        DB 'a'                        DB 'b'                        DB 'c'                        DB 'd'                        DB 'e'                        DB 'f'

 总结:

        这三个伪指令只要是在定义数据的时候使用的     

条件汇编

    说明:

    和C/C++ 中的     #Ifxxx       #else       #endfi      是一样的东西

    基本格式:

    IFXXX     ELSE     ENDIF

    IF/IFE

    判断标的是的值,用法和LINUX SHELL中的用法蛮相似的     IF    (表达式)       表达式 != 0 的时候内容有效     ELSE       表达式 == 0 的时候内容有效     ENDIF               表达式的计算使用  https://www.cnblogs.com/alwaysking/p/7623781.html 中介绍的内容

    IFDEF/IFNDEF

    和C/C++ 中的#ifdef 与#ifndef 意义完全相同

    IFB

    用在宏定义中的,用于判断某个参数 是否为空的     比如     MSG MACRO A,B       ifb   <B>         A    DB 'MR.&B'       else         A     DB 'MR.UNKNOW'       endif      ENDM   

INCLUDE

    说明

    没错与C/C++ 中的含义一致,就是在INCLIDE 的位置直接将INCLUDE的文件的拼接(复制粘贴)进来

    用法

    INCLUDE  A.ASM

    说明

    include后面可以跟路径,和C/C++ 一样,汇编器会首先在当前目录找,之后会在编译参数指定的寻找路径查找文件

 

标签:汇编,13,定义,ENDM,MASM,DB,MOV,AX,BX
来源: https://www.cnblogs.com/alwaysking/p/12261894.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有