zoukankan      html  css  js  c++  java
  • 汇编学习笔记(13)

    结构

        说明:

        是一堆数据的定义的集合

        基本格式:

        结构名称       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++ 一样,汇编器会首先在当前目录找,之后会在编译参数指定的寻找路径查找文件
  • 相关阅读:
    Codeforces Global Round 11
    2018-2019 ICPC, Asia Najing
    Codeforces Round #675 (Div. 2) ABCDE
    AtCoder Regular Contest 104 D(卡常)
    Navigator History Location
    键盘移动div
    键盘事件
    事件的传播
    事件的绑定
    事件的委派
  • 原文地址:https://www.cnblogs.com/alwaysking/p/12261894.html
Copyright © 2011-2022 走看看